kanidm_cli/system_config/
api.rs

1use crate::ApiOpt;
2use std::io::IsTerminal;
3
4impl ApiOpt {
5    pub fn debug(&self) -> bool {
6        match self {
7            ApiOpt::DownloadSchema(asdo) => asdo.copt.debug,
8        }
9    }
10
11    pub async fn exec(&self) {
12        match self {
13            ApiOpt::DownloadSchema(aopt) => {
14                let client = aopt.copt.to_unauth_client();
15                // check if the output file already exists
16                if aopt.filename.exists() {
17                    debug!("Output file {} already exists", aopt.filename.display());
18                    let mut bail = false;
19                    if !aopt.force {
20                        // check if we're in a terminal
21                        if std::io::stdout().is_terminal()
22                            && std::io::stderr().is_terminal()
23                            && std::io::stdin().is_terminal()
24                        {
25                            // validate with the user that it's OK to overwrite
26                            let response = match dialoguer::Confirm::new()
27                                .with_prompt(format!(
28                                    "Output file {} already exists, overwrite?",
29                                    aopt.filename.display()
30                                ))
31                                .interact()
32                            {
33                                Ok(val) => val,
34                                // if it throws an error just trigger false
35                                Err(err) => {
36                                    eprintln!("Failed to get response from user: {:?}", err);
37                                    false
38                                }
39                            };
40                            if !response {
41                                bail = true;
42                            }
43                        } else {
44                            debug!("stdin is not a terminal, bailing!");
45                            bail = true;
46                        }
47                        if bail {
48                            error!("Output file {} already exists and user hasn't forced overwrite, can't continue!", aopt.filename.display());
49                            std::process::exit(1);
50                        }
51                    }
52                }
53                let url = client.make_url("/docs/v1/openapi.json");
54                debug!(
55                    "Downloading schema from {} to {}",
56                    url,
57                    aopt.filename.display()
58                );
59                let jsondata: serde_json::Value =
60                    match client.perform_get_request("/docs/v1/openapi.json").await {
61                        Ok(val) => val,
62                        Err(err) => {
63                            error!("Failed to download: {:?}", err);
64                            std::process::exit(1);
65                        }
66                    };
67                let serialized = match serde_json::to_string_pretty(&jsondata) {
68                    Ok(val) => val,
69                    Err(err) => {
70                        error!("Failed to serialize schema: {:?}", err);
71                        std::process::exit(1);
72                    }
73                };
74
75                match std::fs::write(&aopt.filename, serialized.as_bytes()) {
76                    Ok(_) => {
77                        info!("Wrote schema to {}", aopt.filename.display());
78                    }
79                    Err(err) => {
80                        error!(
81                            "Failed to write schema to {}: {:?}",
82                            aopt.filename.display(),
83                            err
84                        );
85                        std::process::exit(1);
86                    }
87                }
88            }
89        }
90    }
91}