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)) => match opt.output_mode {
167                        OutputMode::Text => println!("{secret}"),
168                        OutputMode::Json => println!("{{\"secret\": \"{secret}\"}}"),
169                    },
170                    Ok(None) => {
171                        opt.output_mode.print_message("No secret configured");
172                    }
173                    Err(e) => handle_client_error(e, opt.output_mode),
174                }
175            }
176            Oauth2Opt::Delete(nopt) => {
177                let client = opt.to_client(OpType::Write).await;
178                match client.idm_oauth2_rs_delete(nopt.name.as_str()).await {
179                    Ok(_) => opt.output_mode.print_message("Success"),
180                    Err(e) => handle_client_error(e, opt.output_mode),
181                }
182            }
183            Oauth2Opt::SetDisplayname(cbopt) => {
184                let client = opt.to_client(OpType::Write).await;
185                match client
186                    .idm_oauth2_rs_update(
187                        cbopt.nopt.name.as_str(),
188                        None,
189                        Some(cbopt.displayname.as_str()),
190                        None,
191                        false,
192                    )
193                    .await
194                {
195                    Ok(_) => opt.output_mode.print_message("Success"),
196                    Err(e) => handle_client_error(e, opt.output_mode),
197                }
198            }
199            Oauth2Opt::SetName { nopt, name } => {
200                let client = opt.to_client(OpType::Write).await;
201                match client
202                    .idm_oauth2_rs_update(
203                        nopt.name.as_str(),
204                        Some(name.as_str()),
205                        None,
206                        None,
207                        false,
208                    )
209                    .await
210                {
211                    Ok(_) => opt.output_mode.print_message("Success"),
212                    Err(e) => handle_client_error(e, opt.output_mode),
213                }
214            }
215            Oauth2Opt::SetLandingUrl { nopt, url } => {
216                let client = opt.to_client(OpType::Write).await;
217                match client
218                    .idm_oauth2_rs_update(nopt.name.as_str(), None, None, Some(url.as_str()), false)
219                    .await
220                {
221                    Ok(_) => opt.output_mode.print_message("Success"),
222                    Err(e) => handle_client_error(e, opt.output_mode),
223                }
224            }
225            Oauth2Opt::SetImage {
226                nopt,
227                path,
228                image_type,
229            } => {
230                let img_res: Result<ImageValue, Error> = (move || {
231                    let file_name = path
232                        .file_name()
233                        .context("Please pass a file")?
234                        .to_str()
235                        .context("Path contains non utf-8")?
236                        .to_string();
237
238                    let image_type = match image_type {
239                        Some(val) => val.clone(),
240                        None => {
241                            path
242                                .extension().context("Path has no extension so we can't infer the imageType, or you could pass the optional imageType argument yourself.")?
243                                .to_str().context("Path contains invalid utf-8")?
244                                .try_into()
245                                .map_err(Error::msg)?
246                        }
247                    };
248
249                    let read_res = read(path);
250                    match read_res {
251                        Ok(data) => Ok(ImageValue::new(file_name, image_type, data)),
252                        Err(err) => {
253                            if opt.debug {
254                                eprintln!(
255                                    "{}",
256                                    kanidm_lib_file_permissions::diagnose_path(path.as_ref())
257                                );
258                            }
259                            Err(err).context(format!("Failed to read file at '{}'", path.display()))
260                        }
261                    }
262                })();
263
264                let img = match img_res {
265                    Ok(img) => img,
266                    Err(err) => {
267                        eprintln!("{err:?}");
268                        return;
269                    }
270                };
271
272                let client = opt.to_client(OpType::Write).await;
273
274                match client
275                    .idm_oauth2_rs_update_image(nopt.name.as_str(), img)
276                    .await
277                {
278                    Ok(_) => opt.output_mode.print_message("Success"),
279                    Err(e) => handle_client_error(e, opt.output_mode),
280                }
281            }
282            Oauth2Opt::RemoveImage(nopt) => {
283                let client = opt.to_client(OpType::Write).await;
284
285                match client.idm_oauth2_rs_delete_image(nopt.name.as_str()).await {
286                    Ok(_) => opt.output_mode.print_message("Success"),
287                    Err(e) => handle_client_error(e, opt.output_mode),
288                }
289            }
290            Oauth2Opt::EnablePkce(nopt) => {
291                let client = opt.to_client(OpType::Write).await;
292                match client.idm_oauth2_rs_enable_pkce(nopt.name.as_str()).await {
293                    Ok(_) => opt.output_mode.print_message("Success"),
294                    Err(e) => handle_client_error(e, opt.output_mode),
295                }
296            }
297            Oauth2Opt::DisablePkce(nopt) => {
298                let client = opt.to_client(OpType::Write).await;
299                match client.idm_oauth2_rs_disable_pkce(nopt.name.as_str()).await {
300                    Ok(_) => opt.output_mode.print_message("Success"),
301                    Err(e) => handle_client_error(e, opt.output_mode),
302                }
303            }
304            Oauth2Opt::EnableLegacyCrypto(nopt) => {
305                let client = opt.to_client(OpType::Write).await;
306                match client
307                    .idm_oauth2_rs_enable_legacy_crypto(nopt.name.as_str())
308                    .await
309                {
310                    Ok(_) => opt.output_mode.print_message("Success"),
311                    Err(e) => handle_client_error(e, opt.output_mode),
312                }
313            }
314            Oauth2Opt::DisableLegacyCrypto(nopt) => {
315                let client = opt.to_client(OpType::Write).await;
316                match client
317                    .idm_oauth2_rs_disable_legacy_crypto(nopt.name.as_str())
318                    .await
319                {
320                    Ok(_) => opt.output_mode.print_message("Success"),
321                    Err(e) => handle_client_error(e, opt.output_mode),
322                }
323            }
324            Oauth2Opt::PreferShortUsername(nopt) => {
325                let client = opt.to_client(OpType::Write).await;
326                match client
327                    .idm_oauth2_rs_prefer_short_username(nopt.name.as_str())
328                    .await
329                {
330                    Ok(_) => opt.output_mode.print_message("Success"),
331                    Err(e) => handle_client_error(e, opt.output_mode),
332                }
333            }
334            Oauth2Opt::PreferSPNUsername(nopt) => {
335                let client = opt.to_client(OpType::Write).await;
336                match client
337                    .idm_oauth2_rs_prefer_spn_username(nopt.name.as_str())
338                    .await
339                {
340                    Ok(_) => opt.output_mode.print_message("Success"),
341                    Err(e) => handle_client_error(e, opt.output_mode),
342                }
343            }
344
345            Oauth2Opt::AddOrigin { name, origin } => {
346                let client = opt.to_client(OpType::Write).await;
347                match client.idm_oauth2_client_add_origin(name, origin).await {
348                    Ok(_) => opt.output_mode.print_message("Success"),
349                    Err(e) => handle_client_error(e, opt.output_mode),
350                }
351            }
352            Oauth2Opt::RemoveOrigin { name, origin } => {
353                let client = opt.to_client(OpType::Write).await;
354                match client.idm_oauth2_client_remove_origin(name, origin).await {
355                    Ok(_) => opt.output_mode.print_message("Success"),
356                    Err(e) => handle_client_error(e, opt.output_mode),
357                }
358            }
359            Oauth2Opt::UpdateClaimMap {
360                name,
361                group,
362                claim_name,
363                values,
364            } => {
365                let client = opt.to_client(OpType::Write).await;
366                match client
367                    .idm_oauth2_rs_update_claim_map(
368                        name.as_str(),
369                        claim_name.as_str(),
370                        group.as_str(),
371                        values,
372                    )
373                    .await
374                {
375                    Ok(_) => opt.output_mode.print_message("Success"),
376                    Err(e) => handle_client_error(e, opt.output_mode),
377                }
378            }
379            Oauth2Opt::UpdateClaimMapJoin {
380                name,
381                claim_name,
382                join,
383            } => {
384                let client = opt.to_client(OpType::Write).await;
385
386                let join = match join {
387                    Oauth2ClaimMapJoin::Csv => ProtoOauth2ClaimMapJoin::Csv,
388                    Oauth2ClaimMapJoin::Ssv => ProtoOauth2ClaimMapJoin::Ssv,
389                    Oauth2ClaimMapJoin::Array => ProtoOauth2ClaimMapJoin::Array,
390                };
391
392                match client
393                    .idm_oauth2_rs_update_claim_map_join(name.as_str(), claim_name.as_str(), join)
394                    .await
395                {
396                    Ok(_) => opt.output_mode.print_message("Success"),
397                    Err(e) => handle_client_error(e, opt.output_mode),
398                }
399            }
400            Oauth2Opt::DeleteClaimMap {
401                name,
402                claim_name,
403                group,
404            } => {
405                let client = opt.to_client(OpType::Write).await;
406                match client
407                    .idm_oauth2_rs_delete_claim_map(
408                        name.as_str(),
409                        claim_name.as_str(),
410                        group.as_str(),
411                    )
412                    .await
413                {
414                    Ok(_) => opt.output_mode.print_message("Success"),
415                    Err(e) => handle_client_error(e, opt.output_mode),
416                }
417            }
418
419            Oauth2Opt::EnablePublicLocalhost { name } => {
420                let client = opt.to_client(OpType::Write).await;
421                match client
422                    .idm_oauth2_rs_enable_public_localhost_redirect(name.as_str())
423                    .await
424                {
425                    Ok(_) => opt.output_mode.print_message("Success"),
426                    Err(e) => handle_client_error(e, opt.output_mode),
427                }
428            }
429
430            Oauth2Opt::DisablePublicLocalhost { name } => {
431                let client = opt.to_client(OpType::Write).await;
432                match client
433                    .idm_oauth2_rs_disable_public_localhost_redirect(name.as_str())
434                    .await
435                {
436                    Ok(_) => opt.output_mode.print_message("Success"),
437                    Err(e) => handle_client_error(e, opt.output_mode),
438                }
439            }
440            Oauth2Opt::EnableStrictRedirectUri { name } => {
441                let client = opt.to_client(OpType::Write).await;
442                match client
443                    .idm_oauth2_rs_enable_strict_redirect_uri(name.as_str())
444                    .await
445                {
446                    Ok(_) => opt.output_mode.print_message("Success"),
447                    Err(e) => handle_client_error(e, opt.output_mode),
448                }
449            }
450
451            Oauth2Opt::DisableStrictRedirectUri { name } => {
452                let client = opt.to_client(OpType::Write).await;
453                match client
454                    .idm_oauth2_rs_disable_strict_redirect_uri(name.as_str())
455                    .await
456                {
457                    Ok(_) => opt.output_mode.print_message("Success"),
458                    Err(e) => handle_client_error(e, opt.output_mode),
459                }
460            }
461            Oauth2Opt::RotateCryptographicKeys { name, rotate_at } => {
462                let client = opt.to_client(OpType::Write).await;
463                match client
464                    .idm_oauth2_rs_rotate_keys(name.as_str(), *rotate_at)
465                    .await
466                {
467                    Ok(_) => opt.output_mode.print_message("Success"),
468                    Err(e) => handle_client_error(e, opt.output_mode),
469                }
470            }
471            Oauth2Opt::RevokeCryptographicKey { name, key_id } => {
472                let client = opt.to_client(OpType::Write).await;
473                match client
474                    .idm_oauth2_rs_revoke_key(name.as_str(), key_id.as_str())
475                    .await
476                {
477                    Ok(_) => opt.output_mode.print_message("Success"),
478                    Err(e) => handle_client_error(e, opt.output_mode),
479                }
480            }
481        }
482    }
483}