1use crate::{handle_client_error, GroupOpt, GroupPosix, KanidmClientParser, OutputMode};
2use kanidm_proto::cli::OpType;
3use kanidm_proto::constants::ATTR_GIDNUMBER;
4
5mod account_policy;
6
7impl GroupOpt {
8 pub async fn exec(&self, opt: KanidmClientParser) {
9 match self {
10 GroupOpt::List => {
11 let client = opt.to_client(OpType::Read).await;
12 match client.idm_group_list().await {
13 Ok(r) => match opt.output_mode {
14 OutputMode::Json => {
15 let r_attrs: Vec<_> = r.iter().map(|entry| &entry.attrs).collect();
16 println!(
17 "{}",
18 serde_json::to_string(&r_attrs).expect("Failed to serialise json")
19 );
20 }
21 OutputMode::Text => r.iter().for_each(|ent| println!("{ent}")),
22 },
23 Err(e) => handle_client_error(e, opt.output_mode),
24 }
25 }
26 GroupOpt::Search { name } => {
27 let client = opt.to_client(OpType::Read).await;
28 match client.idm_group_search(name).await {
29 Ok(r) => match opt.output_mode {
30 OutputMode::Json => {
31 let r_attrs: Vec<_> = r.iter().map(|entry| &entry.attrs).collect();
32 println!(
33 "{}",
34 serde_json::to_string(&r_attrs).expect("Failed to serialise json")
35 );
36 }
37 OutputMode::Text => r.iter().for_each(|ent| println!("{ent}")),
38 },
39 Err(e) => handle_client_error(e, opt.output_mode),
40 }
41 }
42 GroupOpt::Get(gcopt) => {
43 let client = opt.to_client(OpType::Read).await;
44 match client.idm_group_get(gcopt.name.as_str()).await {
46 Ok(Some(e)) => opt.output_mode.print_message(e),
47 Ok(None) => opt
48 .output_mode
49 .print_message(format!("No matching group '{}'", gcopt.name.as_str())),
50 Err(e) => handle_client_error(e, opt.output_mode),
51 }
52 }
53 GroupOpt::Create {
54 name,
55 entry_managed_by,
56 } => {
57 let client = opt.to_client(OpType::Write).await;
58 match client
59 .idm_group_create(name.as_str(), entry_managed_by.as_deref())
60 .await
61 {
62 Err(err) => {
63 error!("Error -> {:?}", err)
64 }
65 Ok(_) => opt
66 .output_mode
67 .print_message(format!("Successfully created group '{}'", name.as_str())),
68 }
69 }
70 GroupOpt::Delete(gcopt) => {
71 let client = opt.to_client(OpType::Write).await;
72 match client.idm_group_delete(gcopt.name.as_str()).await {
73 Err(e) => handle_client_error(e, opt.output_mode),
74 Ok(_) => opt.output_mode.print_message(format!(
75 "Successfully deleted group {}",
76 gcopt.name.as_str()
77 )),
78 }
79 }
80 GroupOpt::PurgeMembers(gcopt) => {
81 let client = opt.to_client(OpType::Write).await;
82 match client.idm_group_purge_members(gcopt.name.as_str()).await {
83 Err(e) => handle_client_error(e, opt.output_mode),
84 Ok(_) => opt.output_mode.print_message(format!(
85 "Successfully purged members of group {}",
86 gcopt.name.as_str()
87 )),
88 }
89 }
90 GroupOpt::ListMembers(gcopt) => {
91 let client = opt.to_client(OpType::Read).await;
92 match client.idm_group_get_members(gcopt.name.as_str()).await {
93 Ok(Some(groups)) => match opt.output_mode {
94 OutputMode::Json => {
95 println!(
96 "{}",
97 serde_json::to_string(&groups)
98 .expect("Failed to serialise groups to JSON")
99 );
100 }
101 OutputMode::Text => groups.iter().for_each(|m| println!("{m:?}")),
102 },
103 Ok(None) => warn!("No members in group {}", gcopt.name.as_str()),
104 Err(e) => handle_client_error(e, opt.output_mode),
105 }
106 }
107 GroupOpt::AddMembers(gcopt) => {
108 let client = opt.to_client(OpType::Write).await;
109 let new_members: Vec<&str> = gcopt.members.iter().map(String::as_str).collect();
110
111 match client
112 .idm_group_add_members(gcopt.name.as_str(), &new_members)
113 .await
114 {
115 Ok(_) => opt.output_mode.print_message(format!(
116 "Successfully added {:?} to group \"{}\"",
117 &new_members,
118 gcopt.name.as_str()
119 )),
120 Err(e) => handle_client_error(e, opt.output_mode),
121 }
122 }
123
124 GroupOpt::RemoveMembers(gcopt) => {
125 let client = opt.to_client(OpType::Write).await;
126 let remove_members: Vec<&str> = gcopt.members.iter().map(String::as_str).collect();
127
128 match client
129 .idm_group_remove_members(gcopt.name.as_str(), &remove_members)
130 .await
131 {
132 Err(e) => {
133 error!("Failed to remove members!");
134 handle_client_error(e, opt.output_mode)
135 }
136 Ok(_) => opt.output_mode.print_message(format!(
137 "Successfully removed members from group {}",
138 gcopt.name
139 )),
140 }
141 }
142 GroupOpt::SetMembers(gcopt) => {
143 let client = opt.to_client(OpType::Write).await;
144 let new_members: Vec<&str> = gcopt.members.iter().map(String::as_str).collect();
145
146 match client
147 .idm_group_set_members(gcopt.name.as_str(), &new_members)
148 .await
149 {
150 Err(e) => handle_client_error(e, opt.output_mode),
151 Ok(_) => opt.output_mode.print_message(format!(
152 "Successfully set members for group {}",
153 gcopt.name
154 )),
155 }
156 }
157 GroupOpt::SetMail { name, mail } => {
158 let client = opt.to_client(OpType::Write).await;
159
160 let result = if mail.is_empty() {
161 client.idm_group_purge_mail(name.as_str()).await
162 } else {
163 client
164 .idm_group_set_mail(name.as_str(), mail.as_slice())
165 .await
166 };
167
168 match result {
169 Err(e) => handle_client_error(e, opt.output_mode),
170 Ok(_) => opt.output_mode.print_message(format!(
171 "Successfully set mail for group {}",
172 name.as_str()
173 )),
174 }
175 }
176 GroupOpt::SetDescription { name, description } => {
177 let client = opt.to_client(OpType::Write).await;
178
179 let result = if let Some(description) = description {
180 client
181 .idm_group_set_description(name.as_str(), description.as_str())
182 .await
183 } else {
184 client.idm_group_purge_description(name.as_str()).await
185 };
186
187 match result {
188 Err(e) => handle_client_error(e, opt.output_mode),
189 Ok(_) => opt.output_mode.print_message(format!(
190 "Successfully set description for group {}",
191 name.as_str()
192 )),
193 }
194 }
195 GroupOpt::Rename { name, new_name } => {
196 let client = opt.to_client(OpType::Write).await;
197
198 let result = client.group_rename(name.as_str(), new_name.as_str()).await;
199
200 match result {
201 Err(e) => handle_client_error(e, opt.output_mode),
202 Ok(_) => opt
203 .output_mode
204 .print_message(format!("Successfully renamed group {name} to {new_name}")),
205 }
206 }
207 GroupOpt::SetEntryManagedBy {
208 name,
209 entry_managed_by,
210 } => {
211 let client = opt.to_client(OpType::Write).await;
212
213 match client
214 .idm_group_set_entry_managed_by(name, entry_managed_by)
215 .await
216 {
217 Err(e) => handle_client_error(e, opt.output_mode),
218 Ok(_) => opt.output_mode.print_message(format!(
219 "Successfully set entry manager to '{entry_managed_by}' for group '{name}'"
220 )),
221 }
222 }
223 GroupOpt::Posix { commands } => match commands {
224 GroupPosix::Show(gcopt) => {
225 let client = opt.to_client(OpType::Read).await;
226 match client.idm_group_unix_token_get(gcopt.name.as_str()).await {
227 Ok(token) => opt.output_mode.print_message(token),
228 Err(e) => handle_client_error(e, opt.output_mode),
229 }
230 }
231 GroupPosix::Set(gcopt) => {
232 let client = opt.to_client(OpType::Write).await;
233 match client
234 .idm_group_unix_extend(gcopt.name.as_str(), gcopt.gidnumber)
235 .await
236 {
237 Err(e) => handle_client_error(e, opt.output_mode),
238 Ok(_) => opt.output_mode.print_message(format!(
239 "Success adding POSIX configuration for group {}",
240 gcopt.name
241 )),
242 }
243 }
244 GroupPosix::ResetGidnumber { group_id } => {
245 let client = opt.to_client(OpType::Write).await;
246 if let Err(e) = client
247 .idm_group_purge_attr(group_id.as_str(), ATTR_GIDNUMBER)
248 .await
249 {
250 handle_client_error(e, opt.output_mode)
251 }
252 }
253 },
254 GroupOpt::AccountPolicy { commands } => commands.exec(opt).await,
255 } }
257}