claude_wrapper/command/
auth.rs1use crate::Claude;
2use crate::command::ClaudeCommand;
3use crate::error::Result;
4use crate::exec::{self, CommandOutput};
5
6#[derive(Debug, Clone, Default)]
21pub struct AuthStatusCommand {
22 json: bool,
23}
24
25impl AuthStatusCommand {
26 #[must_use]
28 pub fn new() -> Self {
29 Self { json: true }
30 }
31
32 #[must_use]
34 pub fn text(mut self) -> Self {
35 self.json = false;
36 self
37 }
38
39 #[cfg(feature = "json")]
41 pub async fn execute_json(&self, claude: &Claude) -> Result<crate::types::AuthStatus> {
42 let mut cmd = self.clone();
43 cmd.json = true;
44
45 let output = exec::run_claude(claude, cmd.args()).await?;
46
47 serde_json::from_str(&output.stdout).map_err(|e| crate::error::Error::Json {
48 message: format!("failed to parse auth status: {e}"),
49 source: e,
50 })
51 }
52}
53
54impl ClaudeCommand for AuthStatusCommand {
55 type Output = CommandOutput;
56
57 fn args(&self) -> Vec<String> {
58 let mut args = vec!["auth".to_string(), "status".to_string()];
59 if self.json {
60 args.push("--json".to_string());
61 } else {
62 args.push("--text".to_string());
63 }
64 args
65 }
66
67 async fn execute(&self, claude: &Claude) -> Result<CommandOutput> {
68 exec::run_claude(claude, self.args()).await
69 }
70}
71
72#[derive(Debug, Clone, Default)]
89pub struct AuthLoginCommand {
90 email: Option<String>,
91 sso: Option<String>,
92}
93
94impl AuthLoginCommand {
95 #[must_use]
97 pub fn new() -> Self {
98 Self::default()
99 }
100
101 #[must_use]
103 pub fn email(mut self, email: impl Into<String>) -> Self {
104 self.email = Some(email.into());
105 self
106 }
107
108 #[must_use]
110 pub fn sso(mut self, provider: impl Into<String>) -> Self {
111 self.sso = Some(provider.into());
112 self
113 }
114}
115
116impl ClaudeCommand for AuthLoginCommand {
117 type Output = CommandOutput;
118
119 fn args(&self) -> Vec<String> {
120 let mut args = vec!["auth".to_string(), "login".to_string()];
121 if let Some(ref email) = self.email {
122 args.push("--email".to_string());
123 args.push(email.clone());
124 }
125 if let Some(ref sso) = self.sso {
126 args.push("--sso".to_string());
127 args.push(sso.clone());
128 }
129 args
130 }
131
132 async fn execute(&self, claude: &Claude) -> Result<CommandOutput> {
133 exec::run_claude(claude, self.args()).await
134 }
135}
136
137#[derive(Debug, Clone, Default)]
151pub struct AuthLogoutCommand;
152
153impl AuthLogoutCommand {
154 #[must_use]
156 pub fn new() -> Self {
157 Self
158 }
159}
160
161impl ClaudeCommand for AuthLogoutCommand {
162 type Output = CommandOutput;
163
164 fn args(&self) -> Vec<String> {
165 vec!["auth".to_string(), "logout".to_string()]
166 }
167
168 async fn execute(&self, claude: &Claude) -> Result<CommandOutput> {
169 exec::run_claude(claude, self.args()).await
170 }
171}
172
173#[derive(Debug, Clone, Default)]
187pub struct SetupTokenCommand;
188
189impl SetupTokenCommand {
190 #[must_use]
192 pub fn new() -> Self {
193 Self
194 }
195}
196
197impl ClaudeCommand for SetupTokenCommand {
198 type Output = CommandOutput;
199
200 fn args(&self) -> Vec<String> {
201 vec!["setup-token".to_string()]
202 }
203
204 async fn execute(&self, claude: &Claude) -> Result<CommandOutput> {
205 exec::run_claude(claude, self.args()).await
206 }
207}
208
209#[cfg(test)]
210mod tests {
211 use super::*;
212
213 #[test]
214 fn test_auth_status_args() {
215 let cmd = AuthStatusCommand::new();
216 assert_eq!(cmd.args(), vec!["auth", "status", "--json"]);
217 }
218
219 #[test]
220 fn test_auth_status_text() {
221 let cmd = AuthStatusCommand::new().text();
222 assert_eq!(cmd.args(), vec!["auth", "status", "--text"]);
223 }
224
225 #[test]
226 fn test_auth_login_default() {
227 let cmd = AuthLoginCommand::new();
228 assert_eq!(cmd.args(), vec!["auth", "login"]);
229 }
230
231 #[test]
232 fn test_auth_login_with_email() {
233 let cmd = AuthLoginCommand::new().email("user@example.com");
234 assert_eq!(
235 cmd.args(),
236 vec!["auth", "login", "--email", "user@example.com"]
237 );
238 }
239
240 #[test]
241 fn test_auth_login_with_sso() {
242 let cmd = AuthLoginCommand::new().sso("okta");
243 assert_eq!(cmd.args(), vec!["auth", "login", "--sso", "okta"]);
244 }
245
246 #[test]
247 fn test_auth_logout() {
248 let cmd = AuthLogoutCommand::new();
249 assert_eq!(cmd.args(), vec!["auth", "logout"]);
250 }
251
252 #[test]
253 fn test_setup_token() {
254 let cmd = SetupTokenCommand::new();
255 assert_eq!(cmd.args(), vec!["setup-token"]);
256 }
257}