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 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 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}