1use crate::api::DiscourseClient;
2use crate::cli::ListFormat;
3use crate::commands::common::{ensure_api_credentials, select_discourse};
4use crate::config::Config;
5use anyhow::Result;
6
7pub fn api_key_list(config: &Config, discourse_name: &str, format: ListFormat) -> Result<()> {
8 let discourse = select_discourse(config, Some(discourse_name))?;
9 ensure_api_credentials(discourse)?;
10 let client = DiscourseClient::new(discourse)?;
11 let keys = client.list_api_keys()?;
12
13 match format {
14 ListFormat::Text => {
15 if keys.is_empty() {
16 println!("No API keys found.");
17 return Ok(());
18 }
19 let desc_width = keys
20 .iter()
21 .map(|k| k.description.as_deref().unwrap_or("-").len())
22 .max()
23 .unwrap_or(0)
24 .max(11);
25 for k in &keys {
26 let desc = k.description.as_deref().unwrap_or("-");
27 let user = k.username.as_deref().unwrap_or("(all-users)");
28 let last = k.last_used_at.as_deref().unwrap_or("never");
29 let status = if k.revoked_at.is_some() {
30 "revoked"
31 } else {
32 "active"
33 };
34 println!(
35 "id:{:<5} {:<width$} user:{:<20} last:{:<25} {}",
36 k.id,
37 desc,
38 user,
39 last,
40 status,
41 width = desc_width
42 );
43 }
44 }
45 ListFormat::Json => println!("{}", serde_json::to_string_pretty(&keys)?),
46 ListFormat::Yaml => println!("{}", serde_yaml::to_string(&keys)?),
47 }
48 Ok(())
49}
50
51pub fn api_key_create(
52 config: &Config,
53 discourse_name: &str,
54 description: &str,
55 username: Option<&str>,
56 format: ListFormat,
57 dry_run: bool,
58) -> Result<()> {
59 let discourse = select_discourse(config, Some(discourse_name))?;
60 ensure_api_credentials(discourse)?;
61 let client = DiscourseClient::new(discourse)?;
62
63 if dry_run {
64 println!(
65 "[dry-run] {}: would create api key \"{}\" for user {}",
66 discourse.name,
67 description,
68 username.unwrap_or("(all-users)")
69 );
70 return Ok(());
71 }
72
73 let created = client.create_api_key(description, username)?;
74
75 match format {
76 ListFormat::Text => {
77 println!("New API key (shown only this once — copy it now):");
78 println!();
79 println!(" {}", created.key);
80 println!();
81 println!("id: {}", created.id);
82 if let Some(d) = &created.description {
83 println!("description: {}", d);
84 }
85 println!(
86 "username: {}",
87 created.username.as_deref().unwrap_or("(all-users)")
88 );
89 if let Some(c) = &created.created_at {
90 println!("created_at: {}", c);
91 }
92 }
93 ListFormat::Json => println!("{}", serde_json::to_string_pretty(&created)?),
94 ListFormat::Yaml => println!("{}", serde_yaml::to_string(&created)?),
95 }
96 Ok(())
97}
98
99pub fn api_key_revoke(
100 config: &Config,
101 discourse_name: &str,
102 key_id: u64,
103 dry_run: bool,
104) -> Result<()> {
105 let discourse = select_discourse(config, Some(discourse_name))?;
106 ensure_api_credentials(discourse)?;
107 let client = DiscourseClient::new(discourse)?;
108
109 if dry_run {
110 println!(
111 "[dry-run] {}: would revoke api key id:{}",
112 discourse.name, key_id
113 );
114 return Ok(());
115 }
116
117 client.revoke_api_key(key_id)?;
118 println!("Revoked api key id:{}", key_id);
119 Ok(())
120}