Skip to content

Commit

Permalink
refactor(address): change password field to Option<String> for better…
Browse files Browse the repository at this point in the history
… handling of credentials
  • Loading branch information
Sma1lboy committed Jan 31, 2025
1 parent 772f896 commit c31c3b4
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 47 deletions.
78 changes: 36 additions & 42 deletions crates/aim-downloader/src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ use crate::netrc::netrc;
pub struct ParsedAddress {
pub server: String,
pub username: String,
pub password: String,
pub password: Option<String>,
pub path_segments: Vec<String>,
pub file: String,
pub with_password: bool,
}

impl PartialEq for ParsedAddress {
Expand Down Expand Up @@ -50,8 +49,13 @@ impl ParsedAddress {
url.username().unwrap()
};

let password = url.password().unwrap_or_else(|| "anonymous".to_string());
if !silent && username != "anonymous" && password != "anonymous" {
let password = if username == "anonymous" || url.password().is_none() {
None
} else {
Some(url.password().unwrap().to_string())
};

if !silent && username != "anonymous" && password.is_some() {
println!("🔑 Parsed credentials from URL.");
}

Expand All @@ -67,38 +71,36 @@ impl ParsedAddress {
.ok_or_else(|| panic!("got empty path segments from url: {url}"))
.unwrap();

let with_password = password != "anonymous";

ParsedAddress {
server,
username,
password,
path_segments,
file,
with_password,
}
}

fn mixin_netrc(
netrc: &Option<netrc::Netrc>,
server: &str,
username: String,
password: String,
) -> (String, String) {
password: Option<String>,
) -> (String, Option<String>) {
let mut user = username.clone();
let mut pass = password.clone();
if !netrc.is_none() && username == "anonymous" && password == "anonymous" {
for host in netrc.as_ref().unwrap().hosts.iter().enumerate() {
let (_i, (netrc_name, machine)) = host;

let mut name = netrc_name.to_string();
if let Some(port) = machine.port {
name = name + ":" + &port.to_string()[..];
}
if server == name {
user.clone_from(&machine.login);
pass = machine.password.clone().unwrap();
break;
let mut pass = password;

if netrc.is_some() && username == "anonymous" && pass.is_none() {
if let Some(netrc) = netrc.as_ref() {
for (_i, (netrc_name, machine)) in netrc.hosts.iter().enumerate() {
let mut name = netrc_name.to_string();
if let Some(port) = machine.port {
name = name + ":" + &port.to_string()[..];
}
if server == name {
user = machine.login.clone();
pass = machine.password.clone();
break;
}
}
}
}
Expand All @@ -111,18 +113,16 @@ async fn parseaddress_operator_equals_works_when_typical() {
let left = ParsedAddress {
server: "do.main".to_string(),
username: "user".to_string(),
password: "pass".to_string(),
password: Some("pass".to_string()),
path_segments: vec!["my".to_string(), "path".to_string()],
file: "pass".to_string(),
with_password: true,
};
let right = ParsedAddress {
server: "do.main".to_string(),
username: "user".to_string(),
password: "pass".to_string(),
password: Some("pass".to_string()),
path_segments: vec!["my".to_string(), "path".to_string()],
file: "pass".to_string(),
with_password: true,
};

assert!(left == right);
Expand All @@ -133,18 +133,16 @@ async fn parseaddress_operator_equals_fails_when_not_equal() {
let left = ParsedAddress {
server: "do.main".to_string(),
username: "user".to_string(),
password: "pass".to_string(),
password: Some("pass".to_string()),
path_segments: vec!["my".to_string(), "path".to_string()],
file: "pass".to_string(),
with_password: true,
};
let right = ParsedAddress {
server: "do".to_string(),
username: "user".to_string(),
password: "pass".to_string(),
password: Some("pass".to_string()),
path_segments: vec!["my".to_string(), "path".to_string()],
file: "pass".to_string(),
with_password: true,
};

assert!(left != right);
Expand All @@ -155,10 +153,9 @@ async fn parse_works() {
let expected = ParsedAddress {
server: "do.main:21".to_string(),
username: "user".to_string(),
password: "pass".to_string(),
password: Some("pass".to_string()),
path_segments: vec!["index".to_string()],
file: "file".to_string(),
with_password: true,
};

let actual = ParsedAddress::parse_address("ftp://user:[email protected]:21/index/file", true);
Expand All @@ -169,12 +166,12 @@ async fn parse_works() {
#[tokio::test]
async fn mixin_works() {
let expected_username = "test";
let expected_password = "p@ssw0rd";
let expected_password = Some("p@ssw0rd".to_string());
let input = "machine example.com login test password p@ssw0rd";
let input = std::io::BufReader::new(input.as_bytes());
let netrc = netrc::Netrc::parse(input).unwrap();
let username_decoded_from_url = "anonymous".to_string();
let password_decoded_from_url = "anonymous".to_string();
let password_decoded_from_url = None;

let (actual_username, actual_password) = ParsedAddress::mixin_netrc(
&Some(netrc),
Expand All @@ -190,12 +187,12 @@ async fn mixin_works() {
#[tokio::test]
async fn mixin_works_with_port() {
let expected_username = "test";
let expected_password = "p@ssw0rd";
let expected_password = Some("p@ssw0rd".to_string());
let input = "machine example.com login test password p@ssw0rd port 443";
let input = std::io::BufReader::new(input.as_bytes());
let netrc = netrc::Netrc::parse(input).unwrap();
let username_decoded_from_url = "anonymous".to_string();
let password_decoded_from_url = "anonymous".to_string();
let password_decoded_from_url = None;

let (actual_username, actual_password) = ParsedAddress::mixin_netrc(
&Some(netrc),
Expand All @@ -213,10 +210,9 @@ async fn parse_works_with_netrc_mixin() {
let expected = ParsedAddress {
server: "do.main:21".to_string(),
username: "test".to_string(),
password: "p@ssw0rd".to_string(),
password: Some("p@ssw0rd".to_string()),
path_segments: vec!["index".to_string()],
file: "file".to_string(),
with_password: true,
};
let data = "machine do.main login test password p@ssw0rd port 21";

Expand All @@ -232,10 +228,9 @@ async fn parse_works_when_ssh_user() {
let expected = ParsedAddress {
server: "localhost:2223".to_string(),
username: "user".to_string(),
password: "anonymous".to_string(),
password: None,
path_segments: vec!["".to_string()],
file: "file".to_string(),
with_password: false,
};

let actual = ParsedAddress::parse_address("ssh://user@localhost:2223/file", true);
Expand All @@ -248,10 +243,9 @@ async fn parse_works_when_not_silent() {
let expected = ParsedAddress {
server: "localhost:2223".to_string(),
username: "user".to_string(),
password: "pass".to_string(),
password: Some("pass".to_string()),
path_segments: vec!["".to_string()],
file: "file".to_string(),
with_password: false,
};

let actual = ParsedAddress::parse_address("ssh://user:pass@localhost:2223/file", false);
Expand Down
10 changes: 5 additions & 5 deletions crates/aim-downloader/src/https.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ impl HTTPSHandler {
reqwest::header::USER_AGENT,
reqwest::header::HeaderValue::from_static(CLIENT_ID),
)
.basic_auth(parsed_address.username, Some(parsed_address.password))
.basic_auth(parsed_address.username, parsed_address.password)
.body(reqwest::Body::wrap_stream(async_stream))
.send()
.await
Expand Down Expand Up @@ -106,7 +106,7 @@ impl HTTPSHandler {
reqwest::header::USER_AGENT,
reqwest::header::HeaderValue::from_static(CLIENT_ID),
)
.basic_auth(parsed_address.username, Some(parsed_address.password))
.basic_auth(parsed_address.username, parsed_address.password)
.send()
.await
.map_err(|_| format!("Failed to GET from {}", &input))
Expand All @@ -133,8 +133,8 @@ impl HTTPSHandler {
reqwest::header::HeaderValue::from_static(CLIENT_ID),
);

if parsed_address.with_password {
request = request.basic_auth(parsed_address.username, Some(parsed_address.password));
if parsed_address.password.is_some() {
request = request.basic_auth(parsed_address.username, parsed_address.password);
}

let res = request
Expand Down Expand Up @@ -173,7 +173,7 @@ impl HTTPSHandler {
reqwest::header::USER_AGENT,
reqwest::header::HeaderValue::from_static(CLIENT_ID),
)
.basic_auth(parsed_address.username, Some(parsed_address.password))
.basic_auth(parsed_address.username, parsed_address.password)
.send()
.await
.map_err(|_| format!("Failed to GET already uploaded size from {}", &output))
Expand Down

0 comments on commit c31c3b4

Please sign in to comment.