Skip to content

Commit

Permalink
fixes #551 issues with leo login and add commands
Browse files Browse the repository at this point in the history
- both bugs were due to missing error handling when JWT was not created
- was a problem only for non-authorized users
- added few minor changes in CLI output making it more helpful
  • Loading branch information
damirka authored and gluax committed Jan 26, 2021
1 parent d7cced6 commit 941cf1e
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 13 deletions.
16 changes: 12 additions & 4 deletions leo/commands/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,13 @@
// leo add -a author -p package_name
//

use crate::{cli::CLI, cli_types::*, config::*, errors::AddError::*};
use crate::{
cli::CLI,
cli_types::*,
config::*,
errors::{AddError::*, CLIError},
};

use leo_package::{
imports::{ImportsDirectory, IMPORTS_DIRECTORY_NAME},
root::Manifest,
Expand Down Expand Up @@ -105,14 +111,16 @@ impl CLI for AddCommand {
}
}

fn output(options: Self::Options) -> Result<Self::Output, crate::errors::CLIError> {
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
// Begin "Adding" context for console logging
let span = tracing::span!(tracing::Level::INFO, "Adding");
let _enter = span.enter();

let token = read_token()?;

// token can only be there if user has signed into Aleo PM
// so we need to verify that token exists before doing anything else
let token = read_token().map_err(|_| -> CLIError { NotAuthorized.into() })?;
let path = current_dir()?;

// Enforce that the current directory is a leo package
Manifest::try_from(path.as_path())?;

Expand Down
104 changes: 98 additions & 6 deletions leo/commands/login.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@ use crate::{
cli::CLI,
cli_types::*,
config::*,
errors::LoginError::{CannotGetToken, NoConnectionFound, NoCredentialsProvided, WrongLoginOrPassword},
errors::{CLIError, LoginError::*},
};

use std::collections::HashMap;

pub const LOGIN_URL: &str = "v1/account/authenticate";
pub const PROFILE_URL: &str = "v1/account/my_profile";

#[derive(Debug)]
pub struct LoginCommand;
Expand Down Expand Up @@ -75,7 +76,7 @@ impl CLI for LoginCommand {
}
}

fn output(options: Self::Options) -> Result<Self::Output, crate::errors::CLIError> {
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
// Begin "Login" context for console logging
let span = tracing::span!(tracing::Level::INFO, "Login");
let _enter = span.enter();
Expand All @@ -86,13 +87,13 @@ impl CLI for LoginCommand {

// Login using username and password
(None, Some(username), Some(password)) => {
let client = reqwest::blocking::Client::new();
let url = format!("{}{}", PACKAGE_MANAGER_URL, LOGIN_URL);

// prepare JSON data to be sent
let mut json = HashMap::new();
json.insert("email_username", username);
json.insert("password", password);

let client = reqwest::blocking::Client::new();
let url = format!("{}{}", PACKAGE_MANAGER_URL, LOGIN_URL);
let response: HashMap<String, String> = match client.post(&url).json(&json).send() {
Ok(result) => match result.json() {
Ok(json) => json,
Expand All @@ -116,7 +117,11 @@ impl CLI for LoginCommand {

// Login using stored JWT credentials.
// TODO (raychu86) Package manager re-authentication from token
(_, _, _) => Some(read_token()?),
(_, _, _) => {
let token = read_token().map_err(|_| -> CLIError { NoCredentialsProvided.into() })?;

Some(token)
}
};

match token {
Expand All @@ -134,4 +139,91 @@ impl CLI for LoginCommand {
}
}
}

fn new<'a, 'b>() -> clap::App<'a, 'b> {
let arguments = &Self::ARGUMENTS
.iter()
.map(|a| {
let mut args = clap::Arg::with_name(a.0).help(a.1).required(a.3).index(a.4);
if !a.2.is_empty() {
args = args.possible_values(a.2);
}
args
})
.collect::<Vec<clap::Arg<'static, 'static>>>();
let flags = &Self::FLAGS
.iter()
.map(|a| clap::Arg::from_usage(a))
.collect::<Vec<clap::Arg<'static, 'static>>>();
let options = &Self::OPTIONS
.iter()
.map(|a| match !a.2.is_empty() {
true => clap::Arg::from_usage(a.0)
.conflicts_with_all(a.1)
.possible_values(a.2)
.requires_all(a.3),
false => clap::Arg::from_usage(a.0).conflicts_with_all(a.1).requires_all(a.3),
})
.collect::<Vec<clap::Arg<'static, 'static>>>();
let subcommands = Self::SUBCOMMANDS.iter().map(|s| {
clap::SubCommand::with_name(s.0)
.about(s.1)
.args(
&s.2.iter()
.map(|a| {
let mut args = clap::Arg::with_name(a.0).help(a.1).required(a.3).index(a.4);
if !a.2.is_empty() {
args = args.possible_values(a.2);
}
args
})
.collect::<Vec<clap::Arg<'static, 'static>>>(),
)
.args(
&s.3.iter()
.map(|a| clap::Arg::from_usage(a))
.collect::<Vec<clap::Arg<'static, 'static>>>(),
)
.args(
&s.4.iter()
.map(|a| match !a.2.is_empty() {
true => clap::Arg::from_usage(a.0)
.conflicts_with_all(a.1)
.possible_values(a.2)
.requires_all(a.3),
false => clap::Arg::from_usage(a.0).conflicts_with_all(a.1).requires_all(a.3),
})
.collect::<Vec<clap::Arg<'static, 'static>>>(),
)
.settings(s.5)
});

clap::SubCommand::with_name(Self::NAME)
.about(Self::ABOUT)
.settings(&[
clap::AppSettings::ColoredHelp,
clap::AppSettings::DisableHelpSubcommand,
clap::AppSettings::DisableVersion,
])
.args(arguments)
.args(flags)
.args(options)
.subcommands(subcommands)
}

fn process(arguments: &clap::ArgMatches) -> Result<(), CLIError> {
// Set logging environment
match arguments.is_present("debug") {
true => crate::logger::init_logger("leo", 2),
false => crate::logger::init_logger("leo", 1),
}

if arguments.subcommand().0 != "update" {
crate::updater::Updater::print_cli();
}

let options = Self::parse(arguments)?;
let _output = Self::output(options)?;
Ok(())
}
}
9 changes: 6 additions & 3 deletions leo/errors/commands/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,18 @@ use std::ffi::OsString;

#[derive(Debug, Error)]
pub enum AddError {
#[error("connection unavailable {:?}", _0)]
#[error("Connection unavailable {:?}", _0)]
ConnectionUnavailable(OsString),

#[error("missing author or package name")]
#[error("Missing author or package name: leo add author/package")]
MissingAuthorOrPackageName,

#[error("invalid remote")]
#[error("Invalid remote")]
InvalidRemote,

#[error("Not authorized in package manager. Use leo login to sign in")]
NotAuthorized,

#[error("{:?}", _0)]
ZipError(OsString),
}

0 comments on commit 941cf1e

Please sign in to comment.