Skip to content

Commit a294aa0

Browse files
committed
make login more resilient to errors
1 parent 87d436a commit a294aa0

File tree

1 file changed

+48
-25
lines changed

1 file changed

+48
-25
lines changed

tmc-langs-cli/src/main.rs

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -567,14 +567,52 @@ fn run() -> Result<()> {
567567
};
568568
let credentials_path = config_dir.join(tmc_dir).join("credentials.json");
569569
if let Ok(file) = File::open(&credentials_path) {
570-
let token: Token = serde_json::from_reader(file).expect("malformed credentials.json");
571-
core.set_token(token);
570+
match serde_json::from_reader(file) {
571+
Ok(token) => core.set_token(token),
572+
Err(e) => {
573+
log::error!(
574+
"Failed to deserialize credentials.json due to \"{}\", deleting",
575+
e
576+
);
577+
fs::remove_file(&credentials_path).with_context(|| {
578+
format!(
579+
"Failed to remove malformed credentials.json file {}",
580+
credentials_path.display()
581+
)
582+
})?;
583+
}
584+
}
572585
};
573586

574587
if let Some(matches) = matches.subcommand_matches("login") {
575588
let email = matches.value_of("email");
576-
let token = matches.value_of("set-access-token");
589+
let set_access_token = matches.value_of("set-access-token");
590+
591+
// get token from argument or server
592+
let token = if let Some(token) = set_access_token {
593+
let mut token_response = StandardTokenResponse::new(
594+
AccessToken::new(token.to_string()),
595+
BasicTokenType::Bearer,
596+
EmptyExtraTokenFields {},
597+
);
598+
token_response.set_scopes(Some(vec![Scope::new("public".to_string())]));
599+
token_response
600+
} else if let Some(email) = email {
601+
// TODO: "Please enter password" and quiet param
602+
let password = rpassword::read_password().context("Failed to read password")?;
603+
let token = core
604+
.authenticate(client_name, email.to_string(), password)
605+
.context("Failed to authenticate with TMC")?;
606+
token
607+
} else {
608+
Error::with_description(
609+
"Either the --email or --set-access-token argument should be given",
610+
ErrorKind::MissingRequiredArgument,
611+
)
612+
.exit();
613+
};
577614

615+
// create token file
578616
if let Some(p) = credentials_path.parent() {
579617
fs::create_dir_all(p)
580618
.with_context(|| format!("Failed to create directory {}", p.display()))?;
@@ -583,37 +621,22 @@ fn run() -> Result<()> {
583621
format!("Failed to create file at {}", credentials_path.display())
584622
})?;
585623

586-
if let Some(token) = token {
587-
let mut token_response = StandardTokenResponse::new(
588-
AccessToken::new(token.to_string()),
589-
BasicTokenType::Bearer,
590-
EmptyExtraTokenFields {},
591-
);
592-
token_response.set_scopes(Some(vec![Scope::new("public".to_string())]));
593-
serde_json::to_writer(credentials_file, &token_response).with_context(|| {
624+
// write token
625+
if let Err(e) = serde_json::to_writer(credentials_file, &token) {
626+
// failed to write token, removing credentials file
627+
fs::remove_file(&credentials_path).with_context(|| {
594628
format!(
595-
"Failed to write access token to {}",
629+
"Failed to remove empty credentials file after failing to write {}",
596630
credentials_path.display()
597631
)
598632
})?;
599-
} else if let Some(email) = email {
600-
// TODO: "Please enter password" and quiet param
601-
let password = rpassword::read_password().context("Failed to read password")?;
602-
core.authenticate(client_name, email.to_string(), password)
603-
.context("Failed to authenticate with TMC")?;
604-
serde_json::to_writer(credentials_file, &token).with_context(|| {
633+
Err(e).with_context(|| {
605634
format!(
606635
"Failed to write credentials to {}",
607636
credentials_path.display()
608637
)
609638
})?;
610-
} else {
611-
Error::with_description(
612-
"Either the email or set-access-token argument should be given",
613-
ErrorKind::MissingRequiredArgument,
614-
)
615-
.exit();
616-
};
639+
}
617640
} else if let Some(_matches) = matches.subcommand_matches("logout") {
618641
if credentials_path.exists() {
619642
fs::remove_file(&credentials_path).with_context(|| {

0 commit comments

Comments
 (0)