From 70d82c3faad9204e47ed514b58c7bd7c5e7cb61a Mon Sep 17 00:00:00 2001 From: khai96_ Date: Sun, 5 May 2019 14:30:13 +0700 Subject: Begin to support multiple auths --- src/args.rs | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) (limited to 'src/args.rs') diff --git a/src/args.rs b/src/args.rs index 63799a0..3972995 100644 --- a/src/args.rs +++ b/src/args.rs @@ -77,8 +77,20 @@ fn parse_interface(src: &str) -> Result { src.parse::() } -/// Checks wether the auth string is valid, i.e. it follows the syntax username:password +/// Parse a string of multiple authentication requirements fn parse_auth(src: &str) -> Result { + let mut required_auth = auth::RequiredAuth::new(); + + for pair in src.split_whitespace().map(parse_single_auth) { + let (username, password) = pair?; + required_auth.insert(username.to_owned(), password); + } + + Ok(required_auth) +} + +/// Parse a single authentication requirement +fn parse_single_auth(src: &str) -> Result<(String, auth::RequiredAuthPassword), ContextualError> { let mut split = src.splitn(3, ':'); let invalid_auth_format = Err(ContextualError::InvalidAuthFormat); @@ -119,10 +131,7 @@ fn parse_auth(src: &str) -> Result { auth::RequiredAuthPassword::Plain(second_part.to_owned()) }; - Ok(auth::RequiredAuth { - username: username.to_owned(), - password, - }) + Ok((username.to_owned(), password)) } /// Parses the command line arguments @@ -172,16 +181,19 @@ mod tests { fn create_required_auth(username: &str, password: &str, encrypt: &str) -> auth::RequiredAuth { use auth::*; use RequiredAuthPassword::*; + let mut required_auth = RequiredAuth::new(); - RequiredAuth { - username: username.to_owned(), - password: match encrypt { + required_auth.insert( + username.to_owned(), + match encrypt { "plain" => Plain(password.to_owned()), "sha256" => Sha256(hex::decode(password.to_owned()).unwrap()), "sha512" => Sha512(hex::decode(password.to_owned()).unwrap()), _ => panic!("Unknown encryption type"), }, - } + ); + + required_auth } #[rstest_parametrize( -- cgit v1.2.3 From fd82250f1b1d594c6cb13943a72626e8a42c08c9 Mon Sep 17 00:00:00 2001 From: khai96_ Date: Sun, 5 May 2019 17:08:37 +0700 Subject: Add unit test for where it provides multiple valid auth strings --- src/args.rs | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'src/args.rs') diff --git a/src/args.rs b/src/args.rs index 3972995..3d6cac4 100644 --- a/src/args.rs +++ b/src/args.rs @@ -202,7 +202,7 @@ mod tests { case("username:sha256:abcd", "username", "abcd", "sha256"), case("username:sha512:abcd", "username", "abcd", "sha512") )] - fn parse_auth_valid(auth_string: &str, username: &str, password: &str, encrypt: &str) { + fn parse_single_auth_valid(auth_string: &str, username: &str, password: &str, encrypt: &str) { assert_eq!( parse_auth(auth_string).unwrap(), create_required_auth(username, password, encrypt), @@ -228,8 +228,32 @@ mod tests { "Invalid format for password hash. Expected hex code" ), )] - fn parse_auth_invalid(auth_string: &str, err_msg: &str) { + fn parse_single_auth_invalid(auth_string: &str, err_msg: &str) { let err = parse_auth(auth_string).unwrap_err(); assert_eq!(format!("{}", err), err_msg.to_owned()); } + + #[test] + fn parse_multiple_auth_valid() -> Result<(), ContextualError> { + let hex2str = |x: &str| hex::decode(x).expect("Invalid hex code"); + + let pairs = [ + ("usr0", auth::RequiredAuthPassword::Plain("pwd0".to_owned())), + ("usr1", auth::RequiredAuthPassword::Plain("pwd1".to_owned())), + ("usr2", auth::RequiredAuthPassword::Sha256(hex2str("abcd"))), + ("usr3", auth::RequiredAuthPassword::Sha512(hex2str("abcd"))), + ]; + + let mut expected = auth::RequiredAuth::new(); + for (username, password) in pairs.iter() { + expected.insert(username.to_owned().to_string(), password.clone()); + } + + assert_eq!( + parse_auth("usr0:pwd0 usr1:pwd1 usr2:sha256:abcd usr3:sha512:abcd")?, + expected, + ); + + Ok(()) + } } -- cgit v1.2.3 From 28f35beb4104bf777f3e84e4fe102599ec405ed6 Mon Sep 17 00:00:00 2001 From: khai96_ Date: Sun, 5 May 2019 21:21:34 +0700 Subject: Refactoring: Use immutable HashMap This should allow compiler to optimize further --- src/args.rs | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'src/args.rs') diff --git a/src/args.rs b/src/args.rs index 3d6cac4..4851b41 100644 --- a/src/args.rs +++ b/src/args.rs @@ -79,12 +79,13 @@ fn parse_interface(src: &str) -> Result { /// Parse a string of multiple authentication requirements fn parse_auth(src: &str) -> Result { - let mut required_auth = auth::RequiredAuth::new(); - - for pair in src.split_whitespace().map(parse_single_auth) { - let (username, password) = pair?; - required_auth.insert(username.to_owned(), password); - } + let required_auth = src + .split_whitespace() + .map(parse_single_auth) + .collect::, ContextualError>>()? + .iter() + .cloned() + .collect::(); Ok(required_auth) } @@ -237,17 +238,15 @@ mod tests { fn parse_multiple_auth_valid() -> Result<(), ContextualError> { let hex2str = |x: &str| hex::decode(x).expect("Invalid hex code"); - let pairs = [ + let expected: auth::RequiredAuth = [ ("usr0", auth::RequiredAuthPassword::Plain("pwd0".to_owned())), ("usr1", auth::RequiredAuthPassword::Plain("pwd1".to_owned())), ("usr2", auth::RequiredAuthPassword::Sha256(hex2str("abcd"))), ("usr3", auth::RequiredAuthPassword::Sha512(hex2str("abcd"))), - ]; - - let mut expected = auth::RequiredAuth::new(); - for (username, password) in pairs.iter() { - expected.insert(username.to_owned().to_string(), password.clone()); - } + ] + .iter() + .map(|(username, password)| (username.to_owned().to_string(), password.clone())) + .collect(); assert_eq!( parse_auth("usr0:pwd0 usr1:pwd1 usr2:sha256:abcd usr3:sha512:abcd")?, -- cgit v1.2.3 From 784b5fd79b071937ca1ade12caf9be291b53dff6 Mon Sep 17 00:00:00 2001 From: khai96_ Date: Thu, 16 May 2019 16:53:27 +0700 Subject: Make some changes --- src/args.rs | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) (limited to 'src/args.rs') diff --git a/src/args.rs b/src/args.rs index 4851b41..0ec8a22 100644 --- a/src/args.rs +++ b/src/args.rs @@ -41,7 +41,7 @@ struct CLIArgs { /// Set authentication. Currently supported formats: /// username:password, username:sha256:hash, username:sha512:hash #[structopt(short = "a", long = "auth", parse(try_from_str = "parse_auth"))] - auth: Option, + auth: Vec, /// Generate a random 6-hexdigit route #[structopt(long = "random-route")] @@ -77,21 +77,8 @@ fn parse_interface(src: &str) -> Result { src.parse::() } -/// Parse a string of multiple authentication requirements +/// Parse authentication requirement fn parse_auth(src: &str) -> Result { - let required_auth = src - .split_whitespace() - .map(parse_single_auth) - .collect::, ContextualError>>()? - .iter() - .cloned() - .collect::(); - - Ok(required_auth) -} - -/// Parse a single authentication requirement -fn parse_single_auth(src: &str) -> Result<(String, auth::RequiredAuthPassword), ContextualError> { let mut split = src.splitn(3, ':'); let invalid_auth_format = Err(ContextualError::InvalidAuthFormat); @@ -132,7 +119,10 @@ fn parse_single_auth(src: &str) -> Result<(String, auth::RequiredAuthPassword), auth::RequiredAuthPassword::Plain(second_part.to_owned()) }; - Ok((username.to_owned(), password)) + Ok(auth::RequiredAuth { + username: username.to_owned(), + password, + }) } /// Parses the command line arguments -- cgit v1.2.3 From 67a0af2bb3b171b6c3cce1b81e08be5929a3ccad Mon Sep 17 00:00:00 2001 From: khai96_ Date: Thu, 16 May 2019 19:52:12 +0700 Subject: Update unit tests --- src/args.rs | 49 +++++++++++++------------------------------------ 1 file changed, 13 insertions(+), 36 deletions(-) (limited to 'src/args.rs') diff --git a/src/args.rs b/src/args.rs index 0ec8a22..39efe7e 100644 --- a/src/args.rs +++ b/src/args.rs @@ -172,19 +172,18 @@ mod tests { fn create_required_auth(username: &str, password: &str, encrypt: &str) -> auth::RequiredAuth { use auth::*; use RequiredAuthPassword::*; - let mut required_auth = RequiredAuth::new(); - - required_auth.insert( - username.to_owned(), - match encrypt { - "plain" => Plain(password.to_owned()), - "sha256" => Sha256(hex::decode(password.to_owned()).unwrap()), - "sha512" => Sha512(hex::decode(password.to_owned()).unwrap()), - _ => panic!("Unknown encryption type"), - }, - ); - required_auth + let password = match encrypt { + "plain" => Plain(password.to_owned()), + "sha256" => Sha256(hex::decode(password.to_owned()).unwrap()), + "sha512" => Sha512(hex::decode(password.to_owned()).unwrap()), + _ => panic!("Unknown encryption type"), + }; + + auth::RequiredAuth { + username: username.to_owned(), + password, + } } #[rstest_parametrize( @@ -193,7 +192,7 @@ mod tests { case("username:sha256:abcd", "username", "abcd", "sha256"), case("username:sha512:abcd", "username", "abcd", "sha512") )] - fn parse_single_auth_valid(auth_string: &str, username: &str, password: &str, encrypt: &str) { + fn parse_auth_valid(auth_string: &str, username: &str, password: &str, encrypt: &str) { assert_eq!( parse_auth(auth_string).unwrap(), create_required_auth(username, password, encrypt), @@ -219,30 +218,8 @@ mod tests { "Invalid format for password hash. Expected hex code" ), )] - fn parse_single_auth_invalid(auth_string: &str, err_msg: &str) { + fn parse_auth_invalid(auth_string: &str, err_msg: &str) { let err = parse_auth(auth_string).unwrap_err(); assert_eq!(format!("{}", err), err_msg.to_owned()); } - - #[test] - fn parse_multiple_auth_valid() -> Result<(), ContextualError> { - let hex2str = |x: &str| hex::decode(x).expect("Invalid hex code"); - - let expected: auth::RequiredAuth = [ - ("usr0", auth::RequiredAuthPassword::Plain("pwd0".to_owned())), - ("usr1", auth::RequiredAuthPassword::Plain("pwd1".to_owned())), - ("usr2", auth::RequiredAuthPassword::Sha256(hex2str("abcd"))), - ("usr3", auth::RequiredAuthPassword::Sha512(hex2str("abcd"))), - ] - .iter() - .map(|(username, password)| (username.to_owned().to_string(), password.clone())) - .collect(); - - assert_eq!( - parse_auth("usr0:pwd0 usr1:pwd1 usr2:sha256:abcd usr3:sha512:abcd")?, - expected, - ); - - Ok(()) - } } -- cgit v1.2.3 From 4e6721096f9b11886f8eff45f40ec8fd23facea2 Mon Sep 17 00:00:00 2001 From: khai96_ Date: Thu, 30 May 2019 17:29:50 +0700 Subject: Fix regression where path cannot be placed after '--auth ' --- src/args.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/args.rs') diff --git a/src/args.rs b/src/args.rs index 11357c2..ab6e81c 100644 --- a/src/args.rs +++ b/src/args.rs @@ -41,7 +41,12 @@ struct CLIArgs { /// Set authentication. Currently supported formats: /// username:password, username:sha256:hash, username:sha512:hash /// (e.g. joe:123, joe:sha256:a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3) - #[structopt(short = "a", long = "auth", parse(try_from_str = "parse_auth"))] + #[structopt( + short = "a", + long = "auth", + parse(try_from_str = "parse_auth"), + raw(number_of_values = "1") + )] auth: Vec, /// Generate a random 6-hexdigit route -- cgit v1.2.3