development
rs 73 lines 2.36 KB
Raw
1 use {
2 crate::{cli::AuthCommand, config, context::Ctx, ui},
3 anyhow::{anyhow, Result},
4 sigit_si_api::{account::incomplete_reason, models::AccountStatus},
5 };
6
7 pub async fn run(ctx: &Ctx, command: AuthCommand) -> Result<()> {
8 match command {
9 AuthCommand::Login { email } => login(ctx, email).await,
10 AuthCommand::Logout => logout(ctx).await,
11 AuthCommand::Status => status(ctx).await,
12 }
13 }
14
15 async fn login(ctx: &Ctx, email: Option<String>) -> Result<()> {
16 let email = match email {
17 Some(email) => email,
18 None => ui::prompt::text("Email")?,
19 };
20 let password = ui::prompt::password("Password")?;
21
22 match ctx.client.sign_in(&email, &password).await? {
23 AccountStatus::Ready { access_token } => {
24 let path = config::write_token(ctx.environment, &access_token)?;
25 ui::success(format!(
26 "Signed in as {}. Token saved to {}.",
27 ui::highlight(&email),
28 path.display()
29 ));
30 Ok(())
31 }
32 AccountStatus::NotFound => Err(anyhow!(
33 "No sigit.si account found for {email}. Sign up at https://sigit.si/auth/signup."
34 )),
35 AccountStatus::Incomplete { status } => Err(anyhow!("{}", incomplete_reason(status))),
36 }
37 }
38
39 async fn logout(ctx: &Ctx) -> Result<()> {
40 // A token file surviving from a previous, now-unauthenticated session
41 // shouldn't block sign-out — clear it locally either way.
42 if ctx.client.token().is_some() {
43 let _ = ctx.client.sign_out().await;
44 }
45 config::clear_token(ctx.environment)?;
46 ui::success("Signed out.");
47 Ok(())
48 }
49
50 async fn status(ctx: &Ctx) -> Result<()> {
51 if ctx.client.token().is_none() {
52 println!("Not signed in to {}. Run `si auth login`.", ctx.environment);
53 return Ok(());
54 }
55
56 match ctx.client.user().await {
57 Ok(user) => ui::emit(ctx.json, &user, |user| {
58 println!(
59 "Signed in to {} as {} <{}>.",
60 ctx.environment,
61 ui::highlight(&user.username),
62 user.email
63 );
64 }),
65 Err(e) if e.is_auth_failure() => {
66 config::clear_token(ctx.environment)?;
67 Err(anyhow!(
68 "Your session has expired. Run `si auth login` to sign in again."
69 ))
70 }
71 Err(e) => Err(e.into()),
72 }
73 }