1use crate::api::ApiClient;
2use crate::config::{Config, ConfigManager};
3use crate::utils::error::{CarpError, CarpResult};
4use colored::*;
5use std::io::{self, Write};
6
7pub struct AuthManager;
9
10impl AuthManager {
11 pub async fn login() -> CarpResult<()> {
13 let config = ConfigManager::load()?;
14 let client = ApiClient::new(&config)?;
15
16 println!("{}", "Login to Carp Registry".bold().green());
17 println!("Enter your credentials:");
18
19 print!("Username: ");
20 io::stdout().flush()?;
21 let mut username = String::new();
22 io::stdin().read_line(&mut username)?;
23 let username = username.trim();
24
25 let password = rpassword::prompt_password("Password: ")?;
26
27 println!("Authenticating...");
28
29 match client.authenticate(username, &password).await {
30 Ok(auth_response) => {
31 ConfigManager::set_api_token(auth_response.token)?;
32 println!("{}", "Successfully logged in!".green().bold());
33 println!("Token expires: {}", auth_response.expires_at.format("%Y-%m-%d %H:%M:%S UTC"));
34 Ok(())
35 }
36 Err(e) => {
37 println!("{} {}", "Login failed:".red().bold(), e);
38 Err(e)
39 }
40 }
41 }
42
43 pub async fn logout() -> CarpResult<()> {
45 ConfigManager::clear_api_token()?;
46 println!("{}", "Successfully logged out!".green().bold());
47 Ok(())
48 }
49
50 pub async fn check_auth() -> CarpResult<bool> {
52 let config = ConfigManager::load()?;
53 Ok(config.api_token.is_some())
54 }
55
56 pub async fn status() -> CarpResult<()> {
58 if Self::check_auth().await? {
59 println!("{}", "Authenticated".green().bold());
60
61 let config = ConfigManager::load()?;
62 println!("Registry: {}", config.registry_url);
63
64 let client = ApiClient::new(&config)?;
66 match client.search("", Some(1), false).await {
67 Ok(_) => println!("Token: {}", "Valid".green()),
68 Err(_) => {
69 println!("Token: {}", "Invalid or expired".red());
70 println!("Run 'carp login' to authenticate again.");
71 }
72 }
73 } else {
74 println!("{}", "Not authenticated".red().bold());
75 println!("Run 'carp login' to authenticate.");
76 }
77 Ok(())
78 }
79
80 pub async fn ensure_authenticated() -> CarpResult<()> {
82 if !Self::check_auth().await? {
83 println!("{}", "Authentication required.".yellow().bold());
84 Self::login().await
85 } else {
86 Ok(())
87 }
88 }
89}