mirror of
https://github.com/AleoHQ/leo.git
synced 2024-11-24 10:52:29 +03:00
Merge pull request #179 from AleoHQ/login_command
Add initial version of the login command
This commit is contained in:
commit
3980ff8e1e
@ -32,9 +32,11 @@ clap = { version = "2.33.0" }
|
||||
colored = { version = "2.0" }
|
||||
env_logger = { version = "0.7" }
|
||||
from-pest = { version = "0.3.1" }
|
||||
lazy_static = { version = "1.4.0" }
|
||||
log = { version = "0.4" }
|
||||
rand = { version = "0.7" }
|
||||
rand_core = { version = "0.5.1" }
|
||||
reqwest = { version = "0.10.7", features = ["blocking", "json"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = { version = "1.0" }
|
||||
toml = { version = "0.5" }
|
||||
|
@ -14,6 +14,8 @@ pub type ArgumentType = (NameType, DescriptionType, RequiredType, IndexType);
|
||||
|
||||
pub type FlagType = &'static str;
|
||||
|
||||
// Format
|
||||
// (argument, conflicts, possible_values, requires)
|
||||
pub type OptionType = (
|
||||
&'static str,
|
||||
&'static [&'static str],
|
||||
|
143
leo/commands/login.rs
Normal file
143
leo/commands/login.rs
Normal file
@ -0,0 +1,143 @@
|
||||
//
|
||||
// Usege:
|
||||
//
|
||||
// leo login <token>
|
||||
// leo login -u username -p password
|
||||
// leo login // not yet implemented
|
||||
//
|
||||
|
||||
use crate::{
|
||||
cli::CLI,
|
||||
cli_types::*,
|
||||
errors::{
|
||||
CLIError::LoginError,
|
||||
LoginError::{CannotGetToken, ConnectionUnavalaible, WrongLoginOrPassword},
|
||||
},
|
||||
};
|
||||
use lazy_static::lazy_static;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fs::{create_dir, File},
|
||||
io,
|
||||
io::prelude::*,
|
||||
path::Path,
|
||||
};
|
||||
|
||||
const PACKAGE_MANAGER_URL: &str = "https://apm-backend-dev.herokuapp.com/";
|
||||
const LOGIN_URL: &str = "api/account/login";
|
||||
|
||||
const LEO_CREDENTIALS_DIR: &str = ".leo";
|
||||
const LEO_CREDENTIALS_FILE: &str = "credentials";
|
||||
|
||||
lazy_static! {
|
||||
static ref LEO_CREDENTIALS_PATH: String = format!("{}/{}", LEO_CREDENTIALS_DIR, LEO_CREDENTIALS_FILE);
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LoginCommand;
|
||||
|
||||
impl LoginCommand {
|
||||
fn write_token(token: &str) -> Result<(), io::Error> {
|
||||
let mut credentials = File::create(LEO_CREDENTIALS_PATH.as_str())?;
|
||||
credentials.write_all(&token.as_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn read_token() -> Result<String, io::Error> {
|
||||
let mut credentials = File::open(LEO_CREDENTIALS_PATH.as_str())?;
|
||||
let mut buf = String::new();
|
||||
credentials.read_to_string(&mut buf)?;
|
||||
Ok(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl CLI for LoginCommand {
|
||||
// Format: token, username, password
|
||||
type Options = (Option<String>, Option<String>, Option<String>);
|
||||
type Output = ();
|
||||
|
||||
const ABOUT: AboutType = "Login to the package manager (*)";
|
||||
const ARGUMENTS: &'static [ArgumentType] = &[
|
||||
// (name, description, required, index)
|
||||
("NAME", "Sets token for login to the package manager", false, 1u64),
|
||||
];
|
||||
const FLAGS: &'static [FlagType] = &[];
|
||||
const NAME: NameType = "login";
|
||||
const OPTIONS: &'static [OptionType] = &[
|
||||
// (argument, conflicts, possible_values, requires)
|
||||
("[username] -u --user=[username] 'Sets a username'", &[], &[], &[]),
|
||||
("[password] -p --password=[password] 'Sets a password'", &[], &[], &[]),
|
||||
];
|
||||
const SUBCOMMANDS: &'static [SubCommandType] = &[];
|
||||
|
||||
fn parse(arguments: &clap::ArgMatches) -> Result<Self::Options, crate::errors::CLIError> {
|
||||
if arguments.is_present("username") && arguments.is_present("password") {
|
||||
return Ok((
|
||||
None,
|
||||
Some(arguments.value_of("username").unwrap().to_string()),
|
||||
Some(arguments.value_of("password").unwrap().to_string()),
|
||||
));
|
||||
}
|
||||
|
||||
match arguments.value_of("NAME") {
|
||||
Some(name) => Ok((Some(name.to_string()), None, None)),
|
||||
None => {
|
||||
// TODO implement JWT
|
||||
Ok((None, None, None))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn output(options: Self::Options) -> Result<Self::Output, crate::errors::CLIError> {
|
||||
let token = match options {
|
||||
// Login using existing token
|
||||
(Some(token), _, _) => token,
|
||||
|
||||
// Login using username and password
|
||||
(None, Some(username), Some(password)) => {
|
||||
let client = reqwest::blocking::Client::new();
|
||||
let url = format!("{}{}", PACKAGE_MANAGER_URL, LOGIN_URL);
|
||||
|
||||
let mut json = HashMap::new();
|
||||
json.insert("email_username", username);
|
||||
json.insert("password", password);
|
||||
|
||||
let response: HashMap<String, String> = match client.post(&url).json(&json).send() {
|
||||
Ok(result) => match result.json() {
|
||||
Ok(json) => json,
|
||||
Err(_error) => {
|
||||
log::error!("Wrong login or password");
|
||||
return Err(LoginError(WrongLoginOrPassword("Wrong login or password".into())));
|
||||
}
|
||||
},
|
||||
//Cannot connect to the server
|
||||
Err(_error) => {
|
||||
return Err(LoginError(ConnectionUnavalaible(
|
||||
"Could not connect to the package manager".into(),
|
||||
)));
|
||||
}
|
||||
};
|
||||
|
||||
match response.get("token") {
|
||||
Some(token) => token.clone(),
|
||||
None => return Err(LoginError(CannotGetToken("There is no token".into()))),
|
||||
}
|
||||
}
|
||||
|
||||
// Login using JWT
|
||||
(_, _, _) => {
|
||||
// TODO JWT
|
||||
unimplemented!()
|
||||
}
|
||||
};
|
||||
|
||||
// Create Leo credentials directory if it not exists
|
||||
if !Path::new(LEO_CREDENTIALS_DIR).exists() {
|
||||
create_dir(LEO_CREDENTIALS_DIR)?;
|
||||
}
|
||||
|
||||
LoginCommand::write_token(token.as_str())?;
|
||||
log::info!("Successfully logged in");
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -16,6 +16,9 @@ pub use self::lint::*;
|
||||
pub mod load;
|
||||
pub use self::load::*;
|
||||
|
||||
pub mod login;
|
||||
pub use self::login::*;
|
||||
|
||||
pub mod new;
|
||||
pub use self::new::*;
|
||||
|
||||
|
@ -30,6 +30,9 @@ pub enum CLIError {
|
||||
#[error("{}", _0)]
|
||||
LibFileError(LibFileError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
LoginError(LoginError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
MainFileError(MainFileError),
|
||||
|
||||
@ -123,6 +126,13 @@ impl From<LibFileError> for CLIError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<LoginError> for CLIError {
|
||||
fn from(error: LoginError) -> Self {
|
||||
log::error!("{}\n", error);
|
||||
CLIError::LoginError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MainFileError> for CLIError {
|
||||
fn from(error: MainFileError) -> Self {
|
||||
log::error!("{}\n", error);
|
||||
|
13
leo/errors/commands/login.rs
Normal file
13
leo/errors/commands/login.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use std::ffi::OsString;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum LoginError {
|
||||
#[error("{:?}", _0)]
|
||||
CannotGetToken(OsString),
|
||||
|
||||
#[error("connectin unavalaible {:?}", _0)]
|
||||
ConnectionUnavalaible(OsString),
|
||||
|
||||
#[error("wrong login or password {:?}", _0)]
|
||||
WrongLoginOrPassword(OsString),
|
||||
}
|
@ -4,6 +4,9 @@ pub use self::build::*;
|
||||
pub mod init;
|
||||
pub use self::init::*;
|
||||
|
||||
pub mod login;
|
||||
pub use self::login::*;
|
||||
|
||||
pub mod new;
|
||||
pub use self::new::*;
|
||||
|
||||
|
@ -30,9 +30,10 @@ fn main() -> Result<(), CLIError> {
|
||||
SetupCommand::new().display_order(7),
|
||||
ProveCommand::new().display_order(8),
|
||||
RunCommand::new().display_order(9),
|
||||
PublishCommand::new().display_order(10),
|
||||
DeployCommand::new().display_order(11),
|
||||
CleanCommand::new().display_order(12),
|
||||
LoginCommand::new().display_order(10),
|
||||
PublishCommand::new().display_order(11),
|
||||
DeployCommand::new().display_order(12),
|
||||
CleanCommand::new().display_order(13),
|
||||
])
|
||||
.set_term_width(0)
|
||||
.get_matches();
|
||||
@ -48,6 +49,7 @@ fn main() -> Result<(), CLIError> {
|
||||
("setup", Some(arguments)) => SetupCommand::process(arguments),
|
||||
("prove", Some(arguments)) => ProveCommand::process(arguments),
|
||||
("run", Some(arguments)) => RunCommand::process(arguments),
|
||||
("login", Some(arguments)) => LoginCommand::process(arguments),
|
||||
("publish", Some(arguments)) => PublishCommand::process(arguments),
|
||||
("deploy", Some(arguments)) => DeployCommand::process(arguments),
|
||||
("clean", Some(arguments)) => CleanCommand::process(arguments),
|
||||
|
Loading…
Reference in New Issue
Block a user