Skip to content

Commit 3a6d2d2

Browse files
authored
Set token via qlty auth login --token <TOKEN> (#1407)
If "" or "-" are provided, token is read from STDIN
1 parent feefcf9 commit 3a6d2d2

File tree

3 files changed

+46
-10
lines changed

3 files changed

+46
-10
lines changed

qlty-cli/src/commands/auth/login.rs

+32-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,42 @@
11
use crate::{Arguments, CommandError, CommandSuccess};
2-
use anyhow::Result;
2+
use anyhow::{Context, Result};
33
use clap::Args;
4-
use qlty_cloud::load_or_retrieve_auth_token;
4+
use console::style;
5+
use dialoguer::Input;
6+
use qlty_cloud::{load_or_retrieve_auth_token, store_auth_token};
57

68
#[derive(Args, Debug)]
7-
pub struct Login {}
9+
pub struct Login {
10+
/// Provide a CLI token manually or use "-" to read from standard input (see https://qlty.sh/user/settings/cli)
11+
#[arg(long)]
12+
pub token: Option<String>,
13+
}
814

915
impl Login {
1016
pub fn execute(&self, _args: &Arguments) -> Result<CommandSuccess, CommandError> {
17+
if let Some(mut token) = self.token.clone() {
18+
if token == "" || token == "-" {
19+
eprintln!(
20+
"Generate a token from {} and paste it here.",
21+
style("https://qlty.sh/user/settings/cli")
22+
.underlined()
23+
.green()
24+
);
25+
token = Input::<String>::new()
26+
.with_prompt("Token")
27+
.interact_text()
28+
.map(|line| line.trim().to_string())
29+
.with_context(|| "Invalid input")?;
30+
}
31+
32+
if !token.starts_with("qltyp_") || token.len() < 32 {
33+
return Err(CommandError::new("Token is invalid"));
34+
}
35+
36+
store_auth_token(&token)?;
37+
eprintln!("{}", style("Token saved successfully.").green());
38+
return CommandSuccess::ok();
39+
}
1140
load_or_retrieve_auth_token()?;
1241
CommandSuccess::ok()
1342
}

qlty-cloud/src/auth/mod.rs

+13-6
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,22 @@ use crate::Client;
55
use anyhow::Result;
66
use auth_flow::{launch_login_server, AppState};
77
use console::style;
8-
use credentials::{delete_token, read_token};
9-
use std::{thread, time::Duration};
8+
use credentials::read_token;
9+
pub use credentials::{delete_token as clear_auth_token, write_token as store_auth_token};
10+
use std::{env, thread, time::Duration};
1011
use tracing::{info, warn};
1112

13+
const TOKEN_ENV_VAR: &str = "QLTY_TOKEN";
14+
1215
pub fn load_or_retrieve_auth_token() -> Result<String> {
16+
if let Ok(token) = env::var(TOKEN_ENV_VAR) {
17+
let token = token.trim().to_string();
18+
if !token.is_empty() {
19+
// bypass validation when env var is set since this is an intentional override of credential lookup
20+
return Ok(token);
21+
}
22+
}
23+
1324
let mut has_token = false;
1425
let auth_token = match read_token() {
1526
Ok(token) => {
@@ -32,10 +43,6 @@ pub fn load_or_retrieve_auth_token() -> Result<String> {
3243
}
3344
}
3445

35-
pub fn clear_auth_token() -> Result<()> {
36-
delete_token()
37-
}
38-
3946
fn validate_auth_token(auth_token: &String) -> Result<()> {
4047
Client::new(None, Some(auth_token.into()))
4148
.get("/user")

qlty-cloud/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ pub mod export;
33
pub mod format;
44

55
use anyhow::Result;
6-
pub use auth::{clear_auth_token, load_or_retrieve_auth_token};
6+
pub use auth::{clear_auth_token, load_or_retrieve_auth_token, store_auth_token};
77
use qlty_config::version::QLTY_VERSION;
88
use ureq::Request;
99

0 commit comments

Comments
 (0)