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