From 25fa9e74faef1809b07a231844801301ddd31e2a Mon Sep 17 00:00:00 2001 From: Louis Vallat Date: Sat, 23 Oct 2021 23:35:30 +0200 Subject: [PATCH] Refactored to give username and password to login function as parameters, and use the clap framework to built the command line interface Signed-off-by: Louis Vallat --- Cargo.lock | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/main.rs | 38 +++++++++++++++++++++++++++++------- src/session.rs | 27 ++++++++++---------------- 4 files changed, 94 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 581450e..fddddba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +dependencies = [ + "winapi", +] + [[package]] name = "assert-json-diff" version = "2.0.1" @@ -83,6 +92,21 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clap" +version = "2.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + [[package]] name = "colored" version = "2.0.0" @@ -374,6 +398,7 @@ dependencies = [ name = "lychee_client" version = "0.1.0" dependencies = [ + "clap", "dotenv", "hyper", "hyper-tls", @@ -764,6 +789,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + [[package]] name = "syn" version = "1.0.80" @@ -789,6 +820,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + [[package]] name = "tokio" version = "1.12.0" @@ -900,6 +940,12 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +[[package]] +name = "unicode-width" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + [[package]] name = "unicode-xid" version = "0.2.2" @@ -912,6 +958,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "want" version = "0.3.0" diff --git a/Cargo.toml b/Cargo.toml index 698e308..a4de9fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ tokio-test = "0.4.2" hyper-tls = "0.5.0" dotenv = "0.15.0" json = "0.12.4" +clap = "2.33.3" [dev-dependencies] mockito = "0.30.0" diff --git a/src/main.rs b/src/main.rs index 4b6d5c2..b3d5345 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ use hyper_tls::HttpsConnector; use hyper::{Body, Client, Response}; -use crate::session::{login, logout}; -use crate::albums::get_albums; +use clap::{Arg, App, SubCommand}; +use crate::session::login; use dotenv::dotenv; mod session; @@ -16,14 +16,38 @@ pub async fn body_to_str(res: Response) -> String { #[tokio::main] async fn main() -> Result<(), Box> { - dotenv().ok(); + let matches = App::new("Lychee CLIent") + .version("0.1.0") + .author("Louis Vallat ") + .about("An Lychee CLI client written in Rust.") + .subcommand( + SubCommand::with_name("login") + .about("Log into a Lychee instance") + .arg(Arg::with_name("username") + .long("username") + .short("u") + .required(true) + .value_name("USERNAME") + .help("Provide the username for the Lychee account.")) + .arg(Arg::with_name("password") + .long("password") + .short("p") + .required(true) + .value_name("PASSWORD") + .help("Provide the password for the lychee account.")) + ) + .get_matches(); + dotenv().ok(); let https = HttpsConnector::new(); let client = Client::builder().build::<_, hyper::Body>(https); - let lychee_session = login(&client).await; - let albums = get_albums(&client, &lychee_session).await; - logout(&client, &lychee_session).await; - println!("{}", albums["albums"].pretty(4)); + + if let Some(matches) = matches.subcommand_matches("login") { + let username = matches.value_of("username").unwrap(); + let password = matches.value_of("password").unwrap(); + let lychee_session = login(&client, username, password).await; + println!("{:?}", lychee_session); + } Ok(()) } diff --git a/src/session.rs b/src/session.rs index 90688e9..4a1c245 100644 --- a/src/session.rs +++ b/src/session.rs @@ -3,11 +3,8 @@ use hyper::{Body, Client, Method, Request, client::HttpConnector, header::{AUTHO use json::object; use crate::body_to_str; -pub async fn login(client: &Client>) -> HeaderValue { - let login_data = object! { - "username": std::env::var("LYCHEE_USERNAME").unwrap(), - "password": std::env::var("LYCHEE_PASSWORD").unwrap() - }; +pub async fn login(client: &Client>, login: &str, password: &str) -> HeaderValue { + let login_data = object! { "username": login, "password": password }; let req = Request::builder() .method(Method::POST) @@ -48,8 +45,6 @@ mod session_tests { let https = HttpsConnector::new(); let client = Client::builder().build::<_, hyper::Body>(https); std::env::set_var("LYCHEE_ENDPOINT", mockito::server_url()); - std::env::set_var("LYCHEE_USERNAME", "username"); - std::env::set_var("LYCHEE_PASSWORD", "password"); std::env::set_var("LYCHEE_API_KEY", "value"); return client; } @@ -92,7 +87,7 @@ mod session_tests { .with_body("true") .with_status(200) .create(); - assert_eq!("demo", tokio_test::block_on(login(&client))); + assert_eq!("demo", tokio_test::block_on(login(&client, "u", "p"))); m1.assert(); let m2 = mock("POST", "/api/Session::login") @@ -102,7 +97,7 @@ mod session_tests { .with_body("true") .with_status(200) .create(); - assert_eq!("value", tokio_test::block_on(login(&client))); + assert_eq!("value", tokio_test::block_on(login(&client, "u", "p"))); m2.assert(); } @@ -116,7 +111,7 @@ mod session_tests { .with_body("false") .create(); - tokio_test::block_on(login(&client)); + tokio_test::block_on(login(&client, "u", "p")); m.assert(); } @@ -130,7 +125,7 @@ mod session_tests { .with_body("true") .with_status(200) .create(); - tokio_test::block_on(login(&client)); + tokio_test::block_on(login(&client, "u", "p")); m.assert(); } @@ -143,7 +138,7 @@ mod session_tests { .with_body("true") .match_header("authorization", "value") .create(); - tokio_test::block_on(login(&client)); + tokio_test::block_on(login(&client, "u", "p")); m1.assert(); std::env::set_var("LYCHEE_API_KEY", "othervalue"); @@ -153,7 +148,7 @@ mod session_tests { .with_body("true") .match_header("authorization", "othervalue") .create(); - tokio_test::block_on(login(&client)); + tokio_test::block_on(login(&client, "u", "p")); m2.assert(); } @@ -167,20 +162,18 @@ mod session_tests { .with_body("true") .match_body(body1.dump().as_str()) .create(); - tokio_test::block_on(login(&client)); + tokio_test::block_on(login(&client, "username", "password")); m1.assert(); let body2 = object!{ "username": "u", "password": "p" }; let client = setup(); - std::env::set_var("LYCHEE_USERNAME", "u"); - std::env::set_var("LYCHEE_PASSWORD", "p"); let m2 = mock("POST", "/api/Session::login") .with_header("content-type", "application/json") .with_header("set-cookie", "demo") .with_body("true") .match_body(body2.dump().as_str()) .create(); - tokio_test::block_on(login(&client)); + tokio_test::block_on(login(&client, "u", "p")); m2.assert(); } }