kanidm_cli/
raw.rs

1use kanidm_proto::cli::OpType;
2use std::collections::BTreeMap;
3use std::error::Error;
4use std::fs::File;
5use std::io::BufReader;
6use std::path::Path;
7
8use kanidm_proto::internal::{Filter, Modify, ModifyList};
9use kanidm_proto::v1::Entry;
10use serde::de::DeserializeOwned;
11
12use crate::{KanidmClientParser, OutputMode, RawOpt};
13
14fn read_file<T: DeserializeOwned, P: AsRef<Path>>(path: P) -> Result<T, Box<dyn Error>> {
15    let f = File::open(path)?;
16    let r = BufReader::new(f);
17
18    Ok(serde_json::from_reader(r)?)
19}
20
21impl RawOpt {
22    pub async fn exec(&self, opt: KanidmClientParser) {
23        match self {
24            RawOpt::Search(sopt) => {
25                let client = opt.to_client(OpType::Read).await;
26
27                let filter: Filter = match serde_json::from_str(sopt.filter.as_str()) {
28                    Ok(f) => f,
29                    Err(e) => {
30                        error!("Error parsing filter -> {:?}", e);
31                        return;
32                    }
33                };
34
35                match client.search(filter).await {
36                    Ok(rset) => match opt.output_mode {
37                        #[allow(clippy::expect_used)]
38                        OutputMode::Json => {
39                            println!(
40                                "{}",
41                                serde_json::to_string(&rset).expect("Failed to serialize entry!")
42                            )
43                        }
44                        OutputMode::Text => {
45                            rset.iter().for_each(|e| println!("{e}"));
46                        }
47                    },
48                    Err(e) => error!("Error -> {:?}", e),
49                }
50            }
51            RawOpt::Create(copt) => {
52                let client = opt.to_client(OpType::Write).await;
53                // Read the file?
54                let r_entries: Vec<BTreeMap<String, Vec<String>>> = match read_file(&copt.file) {
55                    Ok(r) => r,
56                    Err(e) => {
57                        error!("Error -> {:?}", e);
58                        return;
59                    }
60                };
61
62                let entries = r_entries.into_iter().map(|b| Entry { attrs: b }).collect();
63
64                if let Err(e) = client.create(entries).await {
65                    error!("Error -> {:?}", e);
66                }
67            }
68            RawOpt::Modify(mopt) => {
69                let client = opt.to_client(OpType::Write).await;
70                // Read the file?
71                let filter: Filter = match serde_json::from_str(mopt.filter.as_str()) {
72                    Ok(f) => f,
73                    Err(e) => {
74                        error!("Error -> {:?}", e);
75                        return;
76                    }
77                };
78
79                let r_list: Vec<Modify> = match read_file(&mopt.file) {
80                    Ok(r) => r,
81                    Err(e) => {
82                        error!("Error -> {:?}", e);
83                        return;
84                    }
85                };
86
87                let modlist = ModifyList::new_list(r_list);
88                if let Err(e) = client.modify(filter, modlist).await {
89                    error!("Error -> {:?}", e);
90                }
91            }
92            RawOpt::Delete(dopt) => {
93                let client = opt.to_client(OpType::Write).await;
94                let filter: Filter = match serde_json::from_str(dopt.filter.as_str()) {
95                    Ok(f) => f,
96                    Err(e) => {
97                        error!("Error -> {:?}", e);
98                        return;
99                    }
100                };
101
102                if let Err(e) = client.delete(filter).await {
103                    error!("Error -> {:?}", e);
104                }
105            }
106        }
107    }
108}