1use crate::{handle_client_error, Oauth2Opt, OutputMode};
2use crate::{KanidmClientParser, Oauth2ClaimMapJoin};
3use anyhow::{Context, Error};
4use kanidm_proto::cli::OpType;
5use kanidm_proto::internal::{ImageValue, Oauth2ClaimMapJoin as ProtoOauth2ClaimMapJoin};
6use std::fs::read;
7use std::process::exit;
8
9impl Oauth2Opt {
10 pub async fn exec(&self, opt: KanidmClientParser) {
11 match self {
12 #[cfg(feature = "dev-oauth2-device-flow")]
13 Oauth2Opt::DeviceFlowDisable(nopt) => {
14 let client = opt.to_client(OpType::Write).await;
16 match client
17 .idm_oauth2_client_device_flow_update(&nopt.name, true)
18 .await
19 {
20 Ok(_) => opt.output_mode.print_message("Success"),
21 Err(e) => handle_client_error(e, opt.output_mode),
22 }
23 }
24 #[cfg(feature = "dev-oauth2-device-flow")]
25 Oauth2Opt::DeviceFlowEnable(nopt) => {
26 let client = opt.to_client(OpType::Write).await;
28 match client
29 .idm_oauth2_client_device_flow_update(&nopt.name, true)
30 .await
31 {
32 Ok(_) => opt.output_mode.print_message("Success"),
33 Err(e) => handle_client_error(e, opt.output_mode),
34 }
35 }
36 Oauth2Opt::List => {
37 let client = opt.to_client(OpType::Read).await;
38 match client.idm_oauth2_rs_list().await {
39 Ok(r) => match opt.output_mode {
40 OutputMode::Json => {
41 let r_attrs: Vec<_> = r.iter().map(|entry| &entry.attrs).collect();
42 println!(
43 "{}",
44 serde_json::to_string(&r_attrs).expect("Failed to serialise json")
45 );
46 }
47 OutputMode::Text => r.iter().for_each(|ent| println!("{ent}")),
48 },
49 Err(e) => handle_client_error(e, opt.output_mode),
50 }
51 }
52 Oauth2Opt::Get(nopt) => {
53 let client = opt.to_client(OpType::Read).await;
54 match client.idm_oauth2_rs_get(nopt.name.as_str()).await {
55 Ok(Some(e)) => opt.output_mode.print_message(e),
56 Ok(None) => opt.output_mode.print_message("No matching entries"),
57 Err(e) => handle_client_error(e, opt.output_mode),
58 }
59 }
60 Oauth2Opt::CreateBasic {
61 name,
62 displayname,
63 origin,
64 } => {
65 let client = opt.to_client(OpType::Write).await;
66 match client
67 .idm_oauth2_rs_basic_create(
68 name.as_str(),
69 displayname.as_str(),
70 origin.as_str(),
71 )
72 .await
73 {
74 Ok(_) => opt.output_mode.print_message("Success"),
75 Err(e) => handle_client_error(e, opt.output_mode),
76 }
77 }
78 Oauth2Opt::CreatePublic {
79 name,
80 displayname,
81 origin,
82 } => {
83 let client = opt.to_client(OpType::Write).await;
84 match client
85 .idm_oauth2_rs_public_create(
86 name.as_str(),
87 displayname.as_str(),
88 origin.as_str(),
89 )
90 .await
91 {
92 Ok(_) => opt.output_mode.print_message("Success"),
93 Err(e) => handle_client_error(e, opt.output_mode),
94 }
95 }
96 Oauth2Opt::UpdateScopeMap(cbopt) => {
97 let client = opt.to_client(OpType::Write).await;
98 match client
99 .idm_oauth2_rs_update_scope_map(
100 cbopt.nopt.name.as_str(),
101 cbopt.group.as_str(),
102 cbopt.scopes.iter().map(|s| s.as_str()).collect(),
103 )
104 .await
105 {
106 Ok(_) => opt.output_mode.print_message("Success"),
107 Err(e) => handle_client_error(e, opt.output_mode),
108 }
109 }
110 Oauth2Opt::DeleteScopeMap(cbopt) => {
111 let client = opt.to_client(OpType::Write).await;
112 match client
113 .idm_oauth2_rs_delete_scope_map(cbopt.nopt.name.as_str(), cbopt.group.as_str())
114 .await
115 {
116 Ok(_) => opt.output_mode.print_message("Success"),
117 Err(e) => handle_client_error(e, opt.output_mode),
118 }
119 }
120 Oauth2Opt::UpdateSupScopeMap(cbopt) => {
121 let client = opt.to_client(OpType::Write).await;
122 match client
123 .idm_oauth2_rs_update_sup_scope_map(
124 cbopt.nopt.name.as_str(),
125 cbopt.group.as_str(),
126 cbopt.scopes.iter().map(|s| s.as_str()).collect(),
127 )
128 .await
129 {
130 Ok(_) => opt.output_mode.print_message("Success"),
131 Err(e) => {
132 error!("Error -> {:?}", e);
133 exit(1)
134 }
135 }
136 }
137 Oauth2Opt::DeleteSupScopeMap(cbopt) => {
138 let client = opt.to_client(OpType::Write).await;
139 match client
140 .idm_oauth2_rs_delete_sup_scope_map(
141 cbopt.nopt.name.as_str(),
142 cbopt.group.as_str(),
143 )
144 .await
145 {
146 Ok(_) => opt.output_mode.print_message("Success"),
147 Err(e) => handle_client_error(e, opt.output_mode),
148 }
149 }
150 Oauth2Opt::ResetSecrets(cbopt) => {
151 let client = opt.to_client(OpType::Write).await;
152 match client
153 .idm_oauth2_rs_update(cbopt.name.as_str(), None, None, None, true)
154 .await
155 {
156 Ok(_) => opt.output_mode.print_message("Success"),
157 Err(e) => handle_client_error(e, opt.output_mode),
158 }
159 }
160 Oauth2Opt::ShowBasicSecret(nopt) => {
161 let client = opt.to_client(OpType::Read).await;
162 match client
163 .idm_oauth2_rs_get_basic_secret(nopt.name.as_str())
164 .await
165 {
166 Ok(Some(secret)) => {
167 match opt.output_mode {
168 OutputMode::Text => println!("{secret}"),
169 OutputMode::Json => println!("{{\"secret\": \"{secret}\"}}"),
170 }
171 opt.output_mode.print_message("Success");
172 }
173 Ok(None) => {
174 opt.output_mode.print_message("No secret configured");
175 }
176 Err(e) => handle_client_error(e, opt.output_mode),
177 }
178 }
179 Oauth2Opt::Delete(nopt) => {
180 let client = opt.to_client(OpType::Write).await;
181 match client.idm_oauth2_rs_delete(nopt.name.as_str()).await {
182 Ok(_) => opt.output_mode.print_message("Success"),
183 Err(e) => handle_client_error(e, opt.output_mode),
184 }
185 }
186 Oauth2Opt::SetDisplayname(cbopt) => {
187 let client = opt.to_client(OpType::Write).await;
188 match client
189 .idm_oauth2_rs_update(
190 cbopt.nopt.name.as_str(),
191 None,
192 Some(cbopt.displayname.as_str()),
193 None,
194 false,
195 )
196 .await
197 {
198 Ok(_) => opt.output_mode.print_message("Success"),
199 Err(e) => handle_client_error(e, opt.output_mode),
200 }
201 }
202 Oauth2Opt::SetName { nopt, name } => {
203 let client = opt.to_client(OpType::Write).await;
204 match client
205 .idm_oauth2_rs_update(
206 nopt.name.as_str(),
207 Some(name.as_str()),
208 None,
209 None,
210 false,
211 )
212 .await
213 {
214 Ok(_) => opt.output_mode.print_message("Success"),
215 Err(e) => handle_client_error(e, opt.output_mode),
216 }
217 }
218 Oauth2Opt::SetLandingUrl { nopt, url } => {
219 let client = opt.to_client(OpType::Write).await;
220 match client
221 .idm_oauth2_rs_update(nopt.name.as_str(), None, None, Some(url.as_str()), false)
222 .await
223 {
224 Ok(_) => opt.output_mode.print_message("Success"),
225 Err(e) => handle_client_error(e, opt.output_mode),
226 }
227 }
228 Oauth2Opt::SetImage {
229 nopt,
230 path,
231 image_type,
232 } => {
233 let img_res: Result<ImageValue, Error> = (move || {
234 let file_name = path
235 .file_name()
236 .context("Please pass a file")?
237 .to_str()
238 .context("Path contains non utf-8")?
239 .to_string();
240
241 let image_type = match image_type {
242 Some(val) => val.clone(),
243 None => {
244 path
245 .extension().context("Path has no extension so we can't infer the imageType, or you could pass the optional imageType argument yourself.")?
246 .to_str().context("Path contains invalid utf-8")?
247 .try_into()
248 .map_err(Error::msg)?
249 }
250 };
251
252 let read_res = read(path);
253 match read_res {
254 Ok(data) => Ok(ImageValue::new(file_name, image_type, data)),
255 Err(err) => {
256 if opt.debug {
257 eprintln!(
258 "{}",
259 kanidm_lib_file_permissions::diagnose_path(path.as_ref())
260 );
261 }
262 Err(err).context(format!("Failed to read file at '{}'", path.display()))
263 }
264 }
265 })();
266
267 let img = match img_res {
268 Ok(img) => img,
269 Err(err) => {
270 eprintln!("{err:?}");
271 return;
272 }
273 };
274
275 let client = opt.to_client(OpType::Write).await;
276
277 match client
278 .idm_oauth2_rs_update_image(nopt.name.as_str(), img)
279 .await
280 {
281 Ok(_) => opt.output_mode.print_message("Success"),
282 Err(e) => handle_client_error(e, opt.output_mode),
283 }
284 }
285 Oauth2Opt::RemoveImage(nopt) => {
286 let client = opt.to_client(OpType::Write).await;
287
288 match client.idm_oauth2_rs_delete_image(nopt.name.as_str()).await {
289 Ok(_) => opt.output_mode.print_message("Success"),
290 Err(e) => handle_client_error(e, opt.output_mode),
291 }
292 }
293 Oauth2Opt::EnablePkce(nopt) => {
294 let client = opt.to_client(OpType::Write).await;
295 match client.idm_oauth2_rs_enable_pkce(nopt.name.as_str()).await {
296 Ok(_) => opt.output_mode.print_message("Success"),
297 Err(e) => handle_client_error(e, opt.output_mode),
298 }
299 }
300 Oauth2Opt::DisablePkce(nopt) => {
301 let client = opt.to_client(OpType::Write).await;
302 match client.idm_oauth2_rs_disable_pkce(nopt.name.as_str()).await {
303 Ok(_) => opt.output_mode.print_message("Success"),
304 Err(e) => handle_client_error(e, opt.output_mode),
305 }
306 }
307 Oauth2Opt::EnableLegacyCrypto(nopt) => {
308 let client = opt.to_client(OpType::Write).await;
309 match client
310 .idm_oauth2_rs_enable_legacy_crypto(nopt.name.as_str())
311 .await
312 {
313 Ok(_) => opt.output_mode.print_message("Success"),
314 Err(e) => handle_client_error(e, opt.output_mode),
315 }
316 }
317 Oauth2Opt::DisableLegacyCrypto(nopt) => {
318 let client = opt.to_client(OpType::Write).await;
319 match client
320 .idm_oauth2_rs_disable_legacy_crypto(nopt.name.as_str())
321 .await
322 {
323 Ok(_) => opt.output_mode.print_message("Success"),
324 Err(e) => handle_client_error(e, opt.output_mode),
325 }
326 }
327 Oauth2Opt::PreferShortUsername(nopt) => {
328 let client = opt.to_client(OpType::Write).await;
329 match client
330 .idm_oauth2_rs_prefer_short_username(nopt.name.as_str())
331 .await
332 {
333 Ok(_) => opt.output_mode.print_message("Success"),
334 Err(e) => handle_client_error(e, opt.output_mode),
335 }
336 }
337 Oauth2Opt::PreferSPNUsername(nopt) => {
338 let client = opt.to_client(OpType::Write).await;
339 match client
340 .idm_oauth2_rs_prefer_spn_username(nopt.name.as_str())
341 .await
342 {
343 Ok(_) => opt.output_mode.print_message("Success"),
344 Err(e) => handle_client_error(e, opt.output_mode),
345 }
346 }
347
348 Oauth2Opt::AddOrigin { name, origin } => {
349 let client = opt.to_client(OpType::Write).await;
350 match client.idm_oauth2_client_add_origin(name, origin).await {
351 Ok(_) => opt.output_mode.print_message("Success"),
352 Err(e) => handle_client_error(e, opt.output_mode),
353 }
354 }
355 Oauth2Opt::RemoveOrigin { name, origin } => {
356 let client = opt.to_client(OpType::Write).await;
357 match client.idm_oauth2_client_remove_origin(name, origin).await {
358 Ok(_) => opt.output_mode.print_message("Success"),
359 Err(e) => handle_client_error(e, opt.output_mode),
360 }
361 }
362 Oauth2Opt::UpdateClaimMap {
363 name,
364 group,
365 claim_name,
366 values,
367 } => {
368 let client = opt.to_client(OpType::Write).await;
369 match client
370 .idm_oauth2_rs_update_claim_map(
371 name.as_str(),
372 claim_name.as_str(),
373 group.as_str(),
374 values,
375 )
376 .await
377 {
378 Ok(_) => opt.output_mode.print_message("Success"),
379 Err(e) => handle_client_error(e, opt.output_mode),
380 }
381 }
382 Oauth2Opt::UpdateClaimMapJoin {
383 name,
384 claim_name,
385 join,
386 } => {
387 let client = opt.to_client(OpType::Write).await;
388
389 let join = match join {
390 Oauth2ClaimMapJoin::Csv => ProtoOauth2ClaimMapJoin::Csv,
391 Oauth2ClaimMapJoin::Ssv => ProtoOauth2ClaimMapJoin::Ssv,
392 Oauth2ClaimMapJoin::Array => ProtoOauth2ClaimMapJoin::Array,
393 };
394
395 match client
396 .idm_oauth2_rs_update_claim_map_join(name.as_str(), claim_name.as_str(), join)
397 .await
398 {
399 Ok(_) => opt.output_mode.print_message("Success"),
400 Err(e) => handle_client_error(e, opt.output_mode),
401 }
402 }
403 Oauth2Opt::DeleteClaimMap {
404 name,
405 claim_name,
406 group,
407 } => {
408 let client = opt.to_client(OpType::Write).await;
409 match client
410 .idm_oauth2_rs_delete_claim_map(
411 name.as_str(),
412 claim_name.as_str(),
413 group.as_str(),
414 )
415 .await
416 {
417 Ok(_) => opt.output_mode.print_message("Success"),
418 Err(e) => handle_client_error(e, opt.output_mode),
419 }
420 }
421
422 Oauth2Opt::EnablePublicLocalhost { name } => {
423 let client = opt.to_client(OpType::Write).await;
424 match client
425 .idm_oauth2_rs_enable_public_localhost_redirect(name.as_str())
426 .await
427 {
428 Ok(_) => opt.output_mode.print_message("Success"),
429 Err(e) => handle_client_error(e, opt.output_mode),
430 }
431 }
432
433 Oauth2Opt::DisablePublicLocalhost { name } => {
434 let client = opt.to_client(OpType::Write).await;
435 match client
436 .idm_oauth2_rs_disable_public_localhost_redirect(name.as_str())
437 .await
438 {
439 Ok(_) => opt.output_mode.print_message("Success"),
440 Err(e) => handle_client_error(e, opt.output_mode),
441 }
442 }
443 Oauth2Opt::EnableStrictRedirectUri { name } => {
444 let client = opt.to_client(OpType::Write).await;
445 match client
446 .idm_oauth2_rs_enable_strict_redirect_uri(name.as_str())
447 .await
448 {
449 Ok(_) => opt.output_mode.print_message("Success"),
450 Err(e) => handle_client_error(e, opt.output_mode),
451 }
452 }
453
454 Oauth2Opt::DisableStrictRedirectUri { name } => {
455 let client = opt.to_client(OpType::Write).await;
456 match client
457 .idm_oauth2_rs_disable_strict_redirect_uri(name.as_str())
458 .await
459 {
460 Ok(_) => opt.output_mode.print_message("Success"),
461 Err(e) => handle_client_error(e, opt.output_mode),
462 }
463 }
464 Oauth2Opt::RotateCryptographicKeys { name, rotate_at } => {
465 let client = opt.to_client(OpType::Write).await;
466 match client
467 .idm_oauth2_rs_rotate_keys(name.as_str(), *rotate_at)
468 .await
469 {
470 Ok(_) => opt.output_mode.print_message("Success"),
471 Err(e) => handle_client_error(e, opt.output_mode),
472 }
473 }
474 Oauth2Opt::RevokeCryptographicKey { name, key_id } => {
475 let client = opt.to_client(OpType::Write).await;
476 match client
477 .idm_oauth2_rs_revoke_key(name.as_str(), key_id.as_str())
478 .await
479 {
480 Ok(_) => opt.output_mode.print_message("Success"),
481 Err(e) => handle_client_error(e, opt.output_mode),
482 }
483 }
484 }
485 }
486}