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)) => match opt.output_mode {
167 OutputMode::Text => println!("{secret}"),
168 OutputMode::Json => println!("{{\"secret\": \"{secret}\"}}"),
169 },
170 Ok(None) => {
171 opt.output_mode.print_message("No secret configured");
172 }
173 Err(e) => handle_client_error(e, opt.output_mode),
174 }
175 }
176 Oauth2Opt::Delete(nopt) => {
177 let client = opt.to_client(OpType::Write).await;
178 match client.idm_oauth2_rs_delete(nopt.name.as_str()).await {
179 Ok(_) => opt.output_mode.print_message("Success"),
180 Err(e) => handle_client_error(e, opt.output_mode),
181 }
182 }
183 Oauth2Opt::SetDisplayname(cbopt) => {
184 let client = opt.to_client(OpType::Write).await;
185 match client
186 .idm_oauth2_rs_update(
187 cbopt.nopt.name.as_str(),
188 None,
189 Some(cbopt.displayname.as_str()),
190 None,
191 false,
192 )
193 .await
194 {
195 Ok(_) => opt.output_mode.print_message("Success"),
196 Err(e) => handle_client_error(e, opt.output_mode),
197 }
198 }
199 Oauth2Opt::SetName { nopt, name } => {
200 let client = opt.to_client(OpType::Write).await;
201 match client
202 .idm_oauth2_rs_update(
203 nopt.name.as_str(),
204 Some(name.as_str()),
205 None,
206 None,
207 false,
208 )
209 .await
210 {
211 Ok(_) => opt.output_mode.print_message("Success"),
212 Err(e) => handle_client_error(e, opt.output_mode),
213 }
214 }
215 Oauth2Opt::SetLandingUrl { nopt, url } => {
216 let client = opt.to_client(OpType::Write).await;
217 match client
218 .idm_oauth2_rs_update(nopt.name.as_str(), None, None, Some(url.as_str()), false)
219 .await
220 {
221 Ok(_) => opt.output_mode.print_message("Success"),
222 Err(e) => handle_client_error(e, opt.output_mode),
223 }
224 }
225 Oauth2Opt::SetImage {
226 nopt,
227 path,
228 image_type,
229 } => {
230 let img_res: Result<ImageValue, Error> = (move || {
231 let file_name = path
232 .file_name()
233 .context("Please pass a file")?
234 .to_str()
235 .context("Path contains non utf-8")?
236 .to_string();
237
238 let image_type = match image_type {
239 Some(val) => val.clone(),
240 None => {
241 path
242 .extension().context("Path has no extension so we can't infer the imageType, or you could pass the optional imageType argument yourself.")?
243 .to_str().context("Path contains invalid utf-8")?
244 .try_into()
245 .map_err(Error::msg)?
246 }
247 };
248
249 let read_res = read(path);
250 match read_res {
251 Ok(data) => Ok(ImageValue::new(file_name, image_type, data)),
252 Err(err) => {
253 if opt.debug {
254 eprintln!(
255 "{}",
256 kanidm_lib_file_permissions::diagnose_path(path.as_ref())
257 );
258 }
259 Err(err).context(format!("Failed to read file at '{}'", path.display()))
260 }
261 }
262 })();
263
264 let img = match img_res {
265 Ok(img) => img,
266 Err(err) => {
267 eprintln!("{err:?}");
268 return;
269 }
270 };
271
272 let client = opt.to_client(OpType::Write).await;
273
274 match client
275 .idm_oauth2_rs_update_image(nopt.name.as_str(), img)
276 .await
277 {
278 Ok(_) => opt.output_mode.print_message("Success"),
279 Err(e) => handle_client_error(e, opt.output_mode),
280 }
281 }
282 Oauth2Opt::RemoveImage(nopt) => {
283 let client = opt.to_client(OpType::Write).await;
284
285 match client.idm_oauth2_rs_delete_image(nopt.name.as_str()).await {
286 Ok(_) => opt.output_mode.print_message("Success"),
287 Err(e) => handle_client_error(e, opt.output_mode),
288 }
289 }
290 Oauth2Opt::EnablePkce(nopt) => {
291 let client = opt.to_client(OpType::Write).await;
292 match client.idm_oauth2_rs_enable_pkce(nopt.name.as_str()).await {
293 Ok(_) => opt.output_mode.print_message("Success"),
294 Err(e) => handle_client_error(e, opt.output_mode),
295 }
296 }
297 Oauth2Opt::DisablePkce(nopt) => {
298 let client = opt.to_client(OpType::Write).await;
299 match client.idm_oauth2_rs_disable_pkce(nopt.name.as_str()).await {
300 Ok(_) => opt.output_mode.print_message("Success"),
301 Err(e) => handle_client_error(e, opt.output_mode),
302 }
303 }
304 Oauth2Opt::EnableLegacyCrypto(nopt) => {
305 let client = opt.to_client(OpType::Write).await;
306 match client
307 .idm_oauth2_rs_enable_legacy_crypto(nopt.name.as_str())
308 .await
309 {
310 Ok(_) => opt.output_mode.print_message("Success"),
311 Err(e) => handle_client_error(e, opt.output_mode),
312 }
313 }
314 Oauth2Opt::DisableLegacyCrypto(nopt) => {
315 let client = opt.to_client(OpType::Write).await;
316 match client
317 .idm_oauth2_rs_disable_legacy_crypto(nopt.name.as_str())
318 .await
319 {
320 Ok(_) => opt.output_mode.print_message("Success"),
321 Err(e) => handle_client_error(e, opt.output_mode),
322 }
323 }
324 Oauth2Opt::PreferShortUsername(nopt) => {
325 let client = opt.to_client(OpType::Write).await;
326 match client
327 .idm_oauth2_rs_prefer_short_username(nopt.name.as_str())
328 .await
329 {
330 Ok(_) => opt.output_mode.print_message("Success"),
331 Err(e) => handle_client_error(e, opt.output_mode),
332 }
333 }
334 Oauth2Opt::PreferSPNUsername(nopt) => {
335 let client = opt.to_client(OpType::Write).await;
336 match client
337 .idm_oauth2_rs_prefer_spn_username(nopt.name.as_str())
338 .await
339 {
340 Ok(_) => opt.output_mode.print_message("Success"),
341 Err(e) => handle_client_error(e, opt.output_mode),
342 }
343 }
344
345 Oauth2Opt::AddOrigin { name, origin } => {
346 let client = opt.to_client(OpType::Write).await;
347 match client.idm_oauth2_client_add_origin(name, origin).await {
348 Ok(_) => opt.output_mode.print_message("Success"),
349 Err(e) => handle_client_error(e, opt.output_mode),
350 }
351 }
352 Oauth2Opt::RemoveOrigin { name, origin } => {
353 let client = opt.to_client(OpType::Write).await;
354 match client.idm_oauth2_client_remove_origin(name, origin).await {
355 Ok(_) => opt.output_mode.print_message("Success"),
356 Err(e) => handle_client_error(e, opt.output_mode),
357 }
358 }
359 Oauth2Opt::UpdateClaimMap {
360 name,
361 group,
362 claim_name,
363 values,
364 } => {
365 let client = opt.to_client(OpType::Write).await;
366 match client
367 .idm_oauth2_rs_update_claim_map(
368 name.as_str(),
369 claim_name.as_str(),
370 group.as_str(),
371 values,
372 )
373 .await
374 {
375 Ok(_) => opt.output_mode.print_message("Success"),
376 Err(e) => handle_client_error(e, opt.output_mode),
377 }
378 }
379 Oauth2Opt::UpdateClaimMapJoin {
380 name,
381 claim_name,
382 join,
383 } => {
384 let client = opt.to_client(OpType::Write).await;
385
386 let join = match join {
387 Oauth2ClaimMapJoin::Csv => ProtoOauth2ClaimMapJoin::Csv,
388 Oauth2ClaimMapJoin::Ssv => ProtoOauth2ClaimMapJoin::Ssv,
389 Oauth2ClaimMapJoin::Array => ProtoOauth2ClaimMapJoin::Array,
390 };
391
392 match client
393 .idm_oauth2_rs_update_claim_map_join(name.as_str(), claim_name.as_str(), join)
394 .await
395 {
396 Ok(_) => opt.output_mode.print_message("Success"),
397 Err(e) => handle_client_error(e, opt.output_mode),
398 }
399 }
400 Oauth2Opt::DeleteClaimMap {
401 name,
402 claim_name,
403 group,
404 } => {
405 let client = opt.to_client(OpType::Write).await;
406 match client
407 .idm_oauth2_rs_delete_claim_map(
408 name.as_str(),
409 claim_name.as_str(),
410 group.as_str(),
411 )
412 .await
413 {
414 Ok(_) => opt.output_mode.print_message("Success"),
415 Err(e) => handle_client_error(e, opt.output_mode),
416 }
417 }
418
419 Oauth2Opt::EnablePublicLocalhost { name } => {
420 let client = opt.to_client(OpType::Write).await;
421 match client
422 .idm_oauth2_rs_enable_public_localhost_redirect(name.as_str())
423 .await
424 {
425 Ok(_) => opt.output_mode.print_message("Success"),
426 Err(e) => handle_client_error(e, opt.output_mode),
427 }
428 }
429
430 Oauth2Opt::DisablePublicLocalhost { name } => {
431 let client = opt.to_client(OpType::Write).await;
432 match client
433 .idm_oauth2_rs_disable_public_localhost_redirect(name.as_str())
434 .await
435 {
436 Ok(_) => opt.output_mode.print_message("Success"),
437 Err(e) => handle_client_error(e, opt.output_mode),
438 }
439 }
440 Oauth2Opt::EnableStrictRedirectUri { name } => {
441 let client = opt.to_client(OpType::Write).await;
442 match client
443 .idm_oauth2_rs_enable_strict_redirect_uri(name.as_str())
444 .await
445 {
446 Ok(_) => opt.output_mode.print_message("Success"),
447 Err(e) => handle_client_error(e, opt.output_mode),
448 }
449 }
450
451 Oauth2Opt::DisableStrictRedirectUri { name } => {
452 let client = opt.to_client(OpType::Write).await;
453 match client
454 .idm_oauth2_rs_disable_strict_redirect_uri(name.as_str())
455 .await
456 {
457 Ok(_) => opt.output_mode.print_message("Success"),
458 Err(e) => handle_client_error(e, opt.output_mode),
459 }
460 }
461 Oauth2Opt::RotateCryptographicKeys { name, rotate_at } => {
462 let client = opt.to_client(OpType::Write).await;
463 match client
464 .idm_oauth2_rs_rotate_keys(name.as_str(), *rotate_at)
465 .await
466 {
467 Ok(_) => opt.output_mode.print_message("Success"),
468 Err(e) => handle_client_error(e, opt.output_mode),
469 }
470 }
471 Oauth2Opt::RevokeCryptographicKey { name, key_id } => {
472 let client = opt.to_client(OpType::Write).await;
473 match client
474 .idm_oauth2_rs_revoke_key(name.as_str(), key_id.as_str())
475 .await
476 {
477 Ok(_) => opt.output_mode.print_message("Success"),
478 Err(e) => handle_client_error(e, opt.output_mode),
479 }
480 }
481 }
482 }
483}