kanidm_cli/
raw.rs

1use crate::common::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::{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 fn debug(&self) -> bool {
23        match self {
24            RawOpt::Search(sopt) => sopt.commonopts.debug,
25            RawOpt::Create(copt) => copt.commonopts.debug,
26            RawOpt::Modify(mopt) => mopt.commonopts.debug,
27            RawOpt::Delete(dopt) => dopt.commonopts.debug,
28        }
29    }
30
31    pub async fn exec(&self) {
32        match self {
33            RawOpt::Search(sopt) => {
34                let client = sopt.commonopts.to_client(OpType::Read).await;
35
36                let filter: Filter = match serde_json::from_str(sopt.filter.as_str()) {
37                    Ok(f) => f,
38                    Err(e) => {
39                        error!("Error parsing filter -> {:?}", e);
40                        return;
41                    }
42                };
43
44                match client.search(filter).await {
45                    Ok(rset) => match sopt.commonopts.output_mode {
46                        #[allow(clippy::expect_used)]
47                        OutputMode::Json => {
48                            println!(
49                                "{}",
50                                serde_json::to_string(&rset).expect("Failed to serialize entry!")
51                            )
52                        }
53                        OutputMode::Text => {
54                            rset.iter().for_each(|e| println!("{}", e));
55                        }
56                    },
57                    Err(e) => error!("Error -> {:?}", e),
58                }
59            }
60            RawOpt::Create(copt) => {
61                let client = copt.commonopts.to_client(OpType::Write).await;
62                // Read the file?
63                let r_entries: Vec<BTreeMap<String, Vec<String>>> = match read_file(&copt.file) {
64                    Ok(r) => r,
65                    Err(e) => {
66                        error!("Error -> {:?}", e);
67                        return;
68                    }
69                };
70
71                let entries = r_entries.into_iter().map(|b| Entry { attrs: b }).collect();
72
73                if let Err(e) = client.create(entries).await {
74                    error!("Error -> {:?}", e);
75                }
76            }
77            RawOpt::Modify(mopt) => {
78                let client = mopt.commonopts.to_client(OpType::Write).await;
79                // Read the file?
80                let filter: Filter = match serde_json::from_str(mopt.filter.as_str()) {
81                    Ok(f) => f,
82                    Err(e) => {
83                        error!("Error -> {:?}", e);
84                        return;
85                    }
86                };
87
88                let r_list: Vec<Modify> = match read_file(&mopt.file) {
89                    Ok(r) => r,
90                    Err(e) => {
91                        error!("Error -> {:?}", e);
92                        return;
93                    }
94                };
95
96                let modlist = ModifyList::new_list(r_list);
97                if let Err(e) = client.modify(filter, modlist).await {
98                    error!("Error -> {:?}", e);
99                }
100            }
101            RawOpt::Delete(dopt) => {
102                let client = dopt.commonopts.to_client(OpType::Write).await;
103                let filter: Filter = match serde_json::from_str(dopt.filter.as_str()) {
104                    Ok(f) => f,
105                    Err(e) => {
106                        error!("Error -> {:?}", e);
107                        return;
108                    }
109                };
110
111                if let Err(e) = client.delete(filter).await {
112                    error!("Error -> {:?}", e);
113                }
114            }
115        }
116    }
117}