kanidm_cli/
oauth2.rs

1use crate::{handle_client_error, Oauth2Opt, OutputMode};
2use crate::{KanidmClientParser, Oauth2ClaimMapJoin};
3use anyhow::{Context, Error};
4use kanidm_proto::cli::OpType;
5use kanidm_proto::internal::{ImageValue, Oauth2ClaimMapJoin as ProtoOauth2ClaimMapJoin};
6use std::fs::read;
7use std::process::exit;
8
9impl Oauth2Opt {
10    pub async fn exec(&self, opt: KanidmClientParser) {
11        match self {
12            #[cfg(feature = "dev-oauth2-device-flow")]
13            Oauth2Opt::DeviceFlowDisable(nopt) => {
14                // TODO: finish the CLI bits for DeviceFlowDisable
15                let client = opt.to_client(OpType::Write).await;
16                match client
17                    .idm_oauth2_client_device_flow_update(&nopt.name, true)
18                    .await
19                {
20                    Ok(_) => opt.output_mode.print_message("Success"),
21                    Err(e) => handle_client_error(e, opt.output_mode),
22                }
23            }
24            #[cfg(feature = "dev-oauth2-device-flow")]
25            Oauth2Opt::DeviceFlowEnable(nopt) => {
26                // TODO: finish the CLI bits for DeviceFlowEnable
27                let client = opt.to_client(OpType::Write).await;
28                match client
29                    .idm_oauth2_client_device_flow_update(&nopt.name, true)
30                    .await
31                {
32                    Ok(_) => opt.output_mode.print_message("Success"),
33                    Err(e) => handle_client_error(e, opt.output_mode),
34                }
35            }
36            Oauth2Opt::List => {
37                let client = opt.to_client(OpType::Read).await;
38                match client.idm_oauth2_rs_list().await {
39                    Ok(r) => match opt.output_mode {
40                        OutputMode::Json => {
41                            let r_attrs: Vec<_> = r.iter().map(|entry| &entry.attrs).collect();
42                            println!(
43                                "{}",
44                                serde_json::to_string(&r_attrs).expect("Failed to serialise json")
45                            );
46                        }
47                        OutputMode::Text => r.iter().for_each(|ent| println!("{ent}")),
48                    },
49                    Err(e) => handle_client_error(e, opt.output_mode),
50                }
51            }
52            Oauth2Opt::Get(nopt) => {
53                let client = opt.to_client(OpType::Read).await;
54                match client.idm_oauth2_rs_get(nopt.name.as_str()).await {
55                    Ok(Some(e)) => opt.output_mode.print_message(e),
56                    Ok(None) => opt.output_mode.print_message("No matching entries"),
57                    Err(e) => handle_client_error(e, opt.output_mode),
58                }
59            }
60            Oauth2Opt::CreateBasic {
61                name,
62                displayname,
63                origin,
64            } => {
65                let client = opt.to_client(OpType::Write).await;
66                match client
67                    .idm_oauth2_rs_basic_create(
68                        name.as_str(),
69                        displayname.as_str(),
70                        origin.as_str(),
71                    )
72                    .await
73                {
74                    Ok(_) => opt.output_mode.print_message("Success"),
75                    Err(e) => handle_client_error(e, opt.output_mode),
76                }
77            }
78            Oauth2Opt::CreatePublic {
79                name,
80                displayname,
81                origin,
82            } => {
83                let client = opt.to_client(OpType::Write).await;
84                match client
85                    .idm_oauth2_rs_public_create(
86                        name.as_str(),
87                        displayname.as_str(),
88                        origin.as_str(),
89                    )
90                    .await
91                {
92                    Ok(_) => opt.output_mode.print_message("Success"),
93                    Err(e) => handle_client_error(e, opt.output_mode),
94                }
95            }
96            Oauth2Opt::UpdateScopeMap(cbopt) => {
97                let client = opt.to_client(OpType::Write).await;
98                match client
99                    .idm_oauth2_rs_update_scope_map(
100                        cbopt.nopt.name.as_str(),
101                        cbopt.group.as_str(),
102                        cbopt.scopes.iter().map(|s| s.as_str()).collect(),
103                    )
104                    .await
105                {
106                    Ok(_) => opt.output_mode.print_message("Success"),
107                    Err(e) => handle_client_error(e, opt.output_mode),
108                }
109            }
110            Oauth2Opt::DeleteScopeMap(cbopt) => {
111                let client = opt.to_client(OpType::Write).await;
112                match client
113                    .idm_oauth2_rs_delete_scope_map(cbopt.nopt.name.as_str(), cbopt.group.as_str())
114                    .await
115                {
116                    Ok(_) => opt.output_mode.print_message("Success"),
117                    Err(e) => handle_client_error(e, opt.output_mode),
118                }
119            }
120            Oauth2Opt::UpdateSupScopeMap(cbopt) => {
121                let client = opt.to_client(OpType::Write).await;
122                match client
123                    .idm_oauth2_rs_update_sup_scope_map(
124                        cbopt.nopt.name.as_str(),
125                        cbopt.group.as_str(),
126                        cbopt.scopes.iter().map(|s| s.as_str()).collect(),
127                    )
128                    .await
129                {
130                    Ok(_) => opt.output_mode.print_message("Success"),
131                    Err(e) => {
132                        error!("Error -> {:?}", e);
133                        exit(1)
134                    }
135                }
136            }
137            Oauth2Opt::DeleteSupScopeMap(cbopt) => {
138                let client = opt.to_client(OpType::Write).await;
139                match client
140                    .idm_oauth2_rs_delete_sup_scope_map(
141                        cbopt.nopt.name.as_str(),
142                        cbopt.group.as_str(),
143                    )
144                    .await
145                {
146                    Ok(_) => opt.output_mode.print_message("Success"),
147                    Err(e) => handle_client_error(e, opt.output_mode),
148                }
149            }
150            Oauth2Opt::ResetSecrets(cbopt) => {
151                let client = opt.to_client(OpType::Write).await;
152                match client
153                    .idm_oauth2_rs_update(cbopt.name.as_str(), None, None, None, true)
154                    .await
155                {
156                    Ok(_) => opt.output_mode.print_message("Success"),
157                    Err(e) => handle_client_error(e, opt.output_mode),
158                }
159            }
160            Oauth2Opt::ShowBasicSecret(nopt) => {
161                let client = opt.to_client(OpType::Read).await;
162                match client
163                    .idm_oauth2_rs_get_basic_secret(nopt.name.as_str())
164                    .await
165                {
166                    Ok(Some(secret)) => {
167                        match opt.output_mode {
168                            OutputMode::Text => println!("{secret}"),
169                            OutputMode::Json => println!("{{\"secret\": \"{secret}\"}}"),
170                        }
171                        opt.output_mode.print_message("Success");
172                    }
173                    Ok(None) => {
174                        opt.output_mode.print_message("No secret configured");
175                    }
176                    Err(e) => handle_client_error(e, opt.output_mode),
177                }
178            }
179            Oauth2Opt::Delete(nopt) => {
180                let client = opt.to_client(OpType::Write).await;
181                match client.idm_oauth2_rs_delete(nopt.name.as_str()).await {
182                    Ok(_) => opt.output_mode.print_message("Success"),
183                    Err(e) => handle_client_error(e, opt.output_mode),
184                }
185            }
186            Oauth2Opt::SetDisplayname(cbopt) => {
187                let client = opt.to_client(OpType::Write).await;
188                match client
189                    .idm_oauth2_rs_update(
190                        cbopt.nopt.name.as_str(),
191                        None,
192                        Some(cbopt.displayname.as_str()),
193                        None,
194                        false,
195                    )
196                    .await
197                {
198                    Ok(_) => opt.output_mode.print_message("Success"),
199                    Err(e) => handle_client_error(e, opt.output_mode),
200                }
201            }
202            Oauth2Opt::SetName { nopt, name } => {
203                let client = opt.to_client(OpType::Write).await;
204                match client
205                    .idm_oauth2_rs_update(
206                        nopt.name.as_str(),
207                        Some(name.as_str()),
208                        None,
209                        None,
210                        false,
211                    )
212                    .await
213                {
214                    Ok(_) => opt.output_mode.print_message("Success"),
215                    Err(e) => handle_client_error(e, opt.output_mode),
216                }
217            }
218            Oauth2Opt::SetLandingUrl { nopt, url } => {
219                let client = opt.to_client(OpType::Write).await;
220                match client
221                    .idm_oauth2_rs_update(nopt.name.as_str(), None, None, Some(url.as_str()), false)
222                    .await
223                {
224                    Ok(_) => opt.output_mode.print_message("Success"),
225                    Err(e) => handle_client_error(e, opt.output_mode),
226                }
227            }
228            Oauth2Opt::SetImage {
229                nopt,
230                path,
231                image_type,
232            } => {
233                let img_res: Result<ImageValue, Error> = (move || {
234                    let file_name = path
235                        .file_name()
236                        .context("Please pass a file")?
237                        .to_str()
238                        .context("Path contains non utf-8")?
239                        .to_string();
240
241                    let image_type = match image_type {
242                        Some(val) => val.clone(),
243                        None => {
244                            path
245                                .extension().context("Path has no extension so we can't infer the imageType, or you could pass the optional imageType argument yourself.")?
246                                .to_str().context("Path contains invalid utf-8")?
247                                .try_into()
248                                .map_err(Error::msg)?
249                        }
250                    };
251
252                    let read_res = read(path);
253                    match read_res {
254                        Ok(data) => Ok(ImageValue::new(file_name, image_type, data)),
255                        Err(err) => {
256                            if opt.debug {
257                                eprintln!(
258                                    "{}",
259                                    kanidm_lib_file_permissions::diagnose_path(path.as_ref())
260                                );
261                            }
262                            Err(err).context(format!("Failed to read file at '{}'", path.display()))
263                        }
264                    }
265                })();
266
267                let img = match img_res {
268                    Ok(img) => img,
269                    Err(err) => {
270                        eprintln!("{err:?}");
271                        return;
272                    }
273                };
274
275                let client = opt.to_client(OpType::Write).await;
276
277                match client
278                    .idm_oauth2_rs_update_image(nopt.name.as_str(), img)
279                    .await
280                {
281                    Ok(_) => opt.output_mode.print_message("Success"),
282                    Err(e) => handle_client_error(e, opt.output_mode),
283                }
284            }
285            Oauth2Opt::RemoveImage(nopt) => {
286                let client = opt.to_client(OpType::Write).await;
287
288                match client.idm_oauth2_rs_delete_image(nopt.name.as_str()).await {
289                    Ok(_) => opt.output_mode.print_message("Success"),
290                    Err(e) => handle_client_error(e, opt.output_mode),
291                }
292            }
293            Oauth2Opt::EnablePkce(nopt) => {
294                let client = opt.to_client(OpType::Write).await;
295                match client.idm_oauth2_rs_enable_pkce(nopt.name.as_str()).await {
296                    Ok(_) => opt.output_mode.print_message("Success"),
297                    Err(e) => handle_client_error(e, opt.output_mode),
298                }
299            }
300            Oauth2Opt::DisablePkce(nopt) => {
301                let client = opt.to_client(OpType::Write).await;
302                match client.idm_oauth2_rs_disable_pkce(nopt.name.as_str()).await {
303                    Ok(_) => opt.output_mode.print_message("Success"),
304                    Err(e) => handle_client_error(e, opt.output_mode),
305                }
306            }
307            Oauth2Opt::EnableLegacyCrypto(nopt) => {
308                let client = opt.to_client(OpType::Write).await;
309                match client
310                    .idm_oauth2_rs_enable_legacy_crypto(nopt.name.as_str())
311                    .await
312                {
313                    Ok(_) => opt.output_mode.print_message("Success"),
314                    Err(e) => handle_client_error(e, opt.output_mode),
315                }
316            }
317            Oauth2Opt::DisableLegacyCrypto(nopt) => {
318                let client = opt.to_client(OpType::Write).await;
319                match client
320                    .idm_oauth2_rs_disable_legacy_crypto(nopt.name.as_str())
321                    .await
322                {
323                    Ok(_) => opt.output_mode.print_message("Success"),
324                    Err(e) => handle_client_error(e, opt.output_mode),
325                }
326            }
327            Oauth2Opt::PreferShortUsername(nopt) => {
328                let client = opt.to_client(OpType::Write).await;
329                match client
330                    .idm_oauth2_rs_prefer_short_username(nopt.name.as_str())
331                    .await
332                {
333                    Ok(_) => opt.output_mode.print_message("Success"),
334                    Err(e) => handle_client_error(e, opt.output_mode),
335                }
336            }
337            Oauth2Opt::PreferSPNUsername(nopt) => {
338                let client = opt.to_client(OpType::Write).await;
339                match client
340                    .idm_oauth2_rs_prefer_spn_username(nopt.name.as_str())
341                    .await
342                {
343                    Ok(_) => opt.output_mode.print_message("Success"),
344                    Err(e) => handle_client_error(e, opt.output_mode),
345                }
346            }
347
348            Oauth2Opt::AddOrigin { name, origin } => {
349                let client = opt.to_client(OpType::Write).await;
350                match client.idm_oauth2_client_add_origin(name, origin).await {
351                    Ok(_) => opt.output_mode.print_message("Success"),
352                    Err(e) => handle_client_error(e, opt.output_mode),
353                }
354            }
355            Oauth2Opt::RemoveOrigin { name, origin } => {
356                let client = opt.to_client(OpType::Write).await;
357                match client.idm_oauth2_client_remove_origin(name, origin).await {
358                    Ok(_) => opt.output_mode.print_message("Success"),
359                    Err(e) => handle_client_error(e, opt.output_mode),
360                }
361            }
362            Oauth2Opt::UpdateClaimMap {
363                name,
364                group,
365                claim_name,
366                values,
367            } => {
368                let client = opt.to_client(OpType::Write).await;
369                match client
370                    .idm_oauth2_rs_update_claim_map(
371                        name.as_str(),
372                        claim_name.as_str(),
373                        group.as_str(),
374                        values,
375                    )
376                    .await
377                {
378                    Ok(_) => opt.output_mode.print_message("Success"),
379                    Err(e) => handle_client_error(e, opt.output_mode),
380                }
381            }
382            Oauth2Opt::UpdateClaimMapJoin {
383                name,
384                claim_name,
385                join,
386            } => {
387                let client = opt.to_client(OpType::Write).await;
388
389                let join = match join {
390                    Oauth2ClaimMapJoin::Csv => ProtoOauth2ClaimMapJoin::Csv,
391                    Oauth2ClaimMapJoin::Ssv => ProtoOauth2ClaimMapJoin::Ssv,
392                    Oauth2ClaimMapJoin::Array => ProtoOauth2ClaimMapJoin::Array,
393                };
394
395                match client
396                    .idm_oauth2_rs_update_claim_map_join(name.as_str(), claim_name.as_str(), join)
397                    .await
398                {
399                    Ok(_) => opt.output_mode.print_message("Success"),
400                    Err(e) => handle_client_error(e, opt.output_mode),
401                }
402            }
403            Oauth2Opt::DeleteClaimMap {
404                name,
405                claim_name,
406                group,
407            } => {
408                let client = opt.to_client(OpType::Write).await;
409                match client
410                    .idm_oauth2_rs_delete_claim_map(
411                        name.as_str(),
412                        claim_name.as_str(),
413                        group.as_str(),
414                    )
415                    .await
416                {
417                    Ok(_) => opt.output_mode.print_message("Success"),
418                    Err(e) => handle_client_error(e, opt.output_mode),
419                }
420            }
421
422            Oauth2Opt::EnablePublicLocalhost { name } => {
423                let client = opt.to_client(OpType::Write).await;
424                match client
425                    .idm_oauth2_rs_enable_public_localhost_redirect(name.as_str())
426                    .await
427                {
428                    Ok(_) => opt.output_mode.print_message("Success"),
429                    Err(e) => handle_client_error(e, opt.output_mode),
430                }
431            }
432
433            Oauth2Opt::DisablePublicLocalhost { name } => {
434                let client = opt.to_client(OpType::Write).await;
435                match client
436                    .idm_oauth2_rs_disable_public_localhost_redirect(name.as_str())
437                    .await
438                {
439                    Ok(_) => opt.output_mode.print_message("Success"),
440                    Err(e) => handle_client_error(e, opt.output_mode),
441                }
442            }
443            Oauth2Opt::EnableStrictRedirectUri { name } => {
444                let client = opt.to_client(OpType::Write).await;
445                match client
446                    .idm_oauth2_rs_enable_strict_redirect_uri(name.as_str())
447                    .await
448                {
449                    Ok(_) => opt.output_mode.print_message("Success"),
450                    Err(e) => handle_client_error(e, opt.output_mode),
451                }
452            }
453
454            Oauth2Opt::DisableStrictRedirectUri { name } => {
455                let client = opt.to_client(OpType::Write).await;
456                match client
457                    .idm_oauth2_rs_disable_strict_redirect_uri(name.as_str())
458                    .await
459                {
460                    Ok(_) => opt.output_mode.print_message("Success"),
461                    Err(e) => handle_client_error(e, opt.output_mode),
462                }
463            }
464            Oauth2Opt::RotateCryptographicKeys { name, rotate_at } => {
465                let client = opt.to_client(OpType::Write).await;
466                match client
467                    .idm_oauth2_rs_rotate_keys(name.as_str(), *rotate_at)
468                    .await
469                {
470                    Ok(_) => opt.output_mode.print_message("Success"),
471                    Err(e) => handle_client_error(e, opt.output_mode),
472                }
473            }
474            Oauth2Opt::RevokeCryptographicKey { name, key_id } => {
475                let client = opt.to_client(OpType::Write).await;
476                match client
477                    .idm_oauth2_rs_revoke_key(name.as_str(), key_id.as_str())
478                    .await
479                {
480                    Ok(_) => opt.output_mode.print_message("Success"),
481                    Err(e) => handle_client_error(e, opt.output_mode),
482                }
483            }
484        }
485    }
486}