use anyhow::{anyhow, Result}; use base64::engine::general_purpose; use base64::Engine; #[derive(PartialEq, Debug)] pub struct AuthBody { pub login: String, pub password: String, } impl AuthBody { pub fn from_str(input: &[u8]) -> Result { match general_purpose::STANDARD.decode(input) { Ok(decoded_body) => { match String::from_utf8(decoded_body) { Ok(parsed_to_string) => { let separated_words: Vec<&str> = parsed_to_string.split("\x00").collect::>().clone(); if separated_words.len() == 3 { // first segment ignored (might be needed in the future) Ok(AuthBody { login: separated_words[1].to_string(), password: separated_words[2].to_string(), }) } else { return Err(anyhow!("Incorrect auth format")); } } Err(e) => return Err(e.into()), } } Err(e) => return Err(e.into()), } } } #[cfg(test)] mod test { use super::*; #[test] fn test_returning_auth_body() { let orig = b"\x00login\x00pass"; let encoded = general_purpose::STANDARD.encode(orig); let expected = AuthBody { login: "login".to_string(), password: "pass".to_string(), }; let result = AuthBody::from_str(encoded.as_bytes()).unwrap(); assert_eq!(expected, result); } #[test] fn test_ignoring_first_segment() { let orig = b"ignored\x00login\x00pass"; let encoded = general_purpose::STANDARD.encode(orig); let expected = AuthBody { login: "login".to_string(), password: "pass".to_string(), }; let result = AuthBody::from_str(encoded.as_bytes()).unwrap(); assert_eq!(expected, result); } #[test] fn test_returning_auth_body_with_empty_strings() { let orig = b"\x00\x00"; let encoded = general_purpose::STANDARD.encode(orig); let expected = AuthBody { login: "".to_string(), password: "".to_string(), }; let result = AuthBody::from_str(encoded.as_bytes()).unwrap(); assert_eq!(expected, result); } #[test] fn test_fail_if_size_less_then_3() { let orig = b"login\x00pass"; let encoded = general_purpose::STANDARD.encode(orig); let expected = AuthBody { login: "login".to_string(), password: "pass".to_string(), }; let result = AuthBody::from_str(encoded.as_bytes()); assert!(result.is_err()); } #[test] fn test_fail_if_size_greater_then_3() { let orig = b"first\x00login\x00pass\x00other"; let encoded = general_purpose::STANDARD.encode(orig); let expected = AuthBody { login: "login".to_string(), password: "pass".to_string(), }; let result = AuthBody::from_str(encoded.as_bytes()); assert!(result.is_err()); } }