oxyde_cloud_cli/commands/
login.rs1use crate::api_key::api_key_entry;
2use crate::commands::logout::logout;
3use anyhow::{Context, Result};
4use cliclack::log::remark;
5use cliclack::{input, intro, outro, outro_cancel, spinner};
6use oxyde_cloud_client::Client;
7
8pub async fn login() -> Result<()> {
9 intro("Login").context("Failed to show login intro")?;
10
11 let keyring_entry = api_key_entry().context("Failed to access keyring")?;
12
13 if keyring_entry.get_password().is_ok() {
14 outro("You're already logged in.").context("Failed to show outro message")?;
15 return Ok(());
16 }
17
18 remark("Get your API-Key from https://oxyde.cloud/dashboard/profile/api-key")
19 .context("Failed to show API key instructions")?;
20
21 let api_key: String = input("Paste your API key")
22 .placeholder("ABCD-efgh-IJKL-mnop")
23 .interact()
24 .context("Failed to get API key input")?;
25
26 let api_key = api_key.trim().to_string();
27
28 keyring_entry
29 .set_password(&api_key)
30 .context("Failed to store API key in keyring")?;
31
32 let spinner = spinner();
33 spinner.start("Logging in...");
34
35 match Client::new(api_key).login().await {
36 Ok(login_result) => {
37 spinner.stop("Done!");
38 outro(format!(
39 "You're now logged in as {}.",
40 login_result.username
41 ))
42 .context("Failed to show login success message")?;
43 }
44 Err(err) => {
45 logout().context("Failed to logout after login error")?;
46
47 spinner.error("Failed!");
48 outro_cancel(format!("Failed to login: {err}"))
49 .context("Failed to show login error message")?;
50 }
51 }
52
53 Ok(())
54}