/
basuev
/
gverse
Обзор
Документация
Войти
/
basuev
/
gverse
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/api/auth.rs
111 строк
3 KB
basuev
initial commit: gverse v0.1.0
27 май 2026, 08:52
27 май 2026, 08:52
98b24dd
Код
Авторство
О чём код?
use crate::client::Client; use crate::config::{Config, DEFAULT_API_VERSION, DEFAULT_AUTH_SCHEME, DEFAULT_BASE_URL, Profile}; use crate::error::Result; use crate::output::{Format, print_value}; use clap::Subcommand; #[derive(Subcommand, Debug)] pub enum AuthCmd { Login { #[arg(long, env = "GVERSE_TOKEN")] token: String, #[arg(long, default_value = "default")] name: String, #[arg(long, default_value = DEFAULT_BASE_URL)] base_url: String, #[arg(long, default_value = DEFAULT_API_VERSION)] api_version: String, #[arg(long, default_value = DEFAULT_AUTH_SCHEME, value_parser = ["token", "bearer"])] auth_scheme: String, }, Logout { #[arg(long, default_value = "default")] name: String, }, Status, Whoami, } pub async fn run(cmd: AuthCmd, cfg: &Config, profile: Option<&str>, fmt: Format) -> Result<()> { match cmd { AuthCmd::Login { token, name, base_url, api_version, auth_scheme, } => login(cfg, token, name, base_url, api_version, auth_scheme).await, AuthCmd::Logout { name } => logout(cfg, &name), AuthCmd::Status => status(cfg), AuthCmd::Whoami => whoami(cfg, profile, fmt).await, } } async fn login( cfg: &Config, token: String, name: String, base_url: String, api_version: String, auth_scheme: String, ) -> Result<()> { let mut cfg = cfg.clone(); let profile = Profile { token, base_url, api_version, auth_scheme, user: None, }; let client = Client::new(&profile)?; let me = client.get_value("/user", &[]).await?; let login_name = me.get("login").and_then(|v| v.as_str()).map(String::from); let stored = Profile { user: login_name.clone(), ..profile }; cfg.profiles.insert(name.clone(), stored); if cfg.default_profile.is_none() { cfg.default_profile = Some(name.clone()); } cfg.save()?; let displayed = login_name.unwrap_or_else(|| "?".to_string()); eprintln!("logged in as `{displayed}` (profile `{name}`)"); Ok(()) } fn logout(cfg: &Config, name: &str) -> Result<()> { let mut cfg = cfg.clone(); cfg.profiles.remove(name); if cfg.default_profile.as_deref() == Some(name) { cfg.default_profile = cfg.profiles.keys().next().cloned(); } cfg.save()?; eprintln!("removed profile `{name}`"); Ok(()) } fn status(cfg: &Config) -> Result<()> { if cfg.profiles.is_empty() { println!("not authenticated"); return Ok(()); } for (name, p) in &cfg.profiles { let marker = if cfg.default_profile.as_deref() == Some(name) { "*" } else { " " }; let user = p.user.as_deref().unwrap_or("?"); println!("{marker} {name}: {} (user: {user})", p.base_url); } Ok(()) } async fn whoami(cfg: &Config, profile: Option<&str>, fmt: Format) -> Result<()> { let p = cfg.active_profile(profile)?; let client = Client::new(p)?; let me = client.get_value("/user", &[]).await?; print_value(fmt, &me); Ok(()) }