diff --git a/crates/uv/src/commands/auth/login.rs b/crates/uv/src/commands/auth/login.rs index 73c62fe80..19ab50c9f 100644 --- a/crates/uv/src/commands/auth/login.rs +++ b/crates/uv/src/commands/auth/login.rs @@ -108,6 +108,9 @@ pub(crate) async fn login( bail!("No username provided; did you mean to provide `--username` or `--token`?"); } }; + if username.is_empty() { + bail!("Username cannot be empty"); + } let password = match (password, url_password, token) { (Some(_), Some(_), _) => { @@ -138,6 +141,10 @@ pub(crate) async fn login( } }; + if password.is_empty() { + bail!("Password cannot be empty"); + } + let display_url = if username == "__token__" { url.without_credentials().to_string() } else { diff --git a/crates/uv/src/commands/auth/logout.rs b/crates/uv/src/commands/auth/logout.rs index 6e64dda49..0165fb693 100644 --- a/crates/uv/src/commands/auth/logout.rs +++ b/crates/uv/src/commands/auth/logout.rs @@ -50,6 +50,9 @@ pub(crate) async fn logout( (None, Some(url)) => url.to_string(), (None, None) => "__token__".to_string(), }; + if username.is_empty() { + bail!("Username cannot be empty"); + } let display_url = if username == "__token__" { url.without_credentials().to_string() diff --git a/crates/uv/src/commands/auth/token.rs b/crates/uv/src/commands/auth/token.rs index 369b2dd55..9853919d8 100644 --- a/crates/uv/src/commands/auth/token.rs +++ b/crates/uv/src/commands/auth/token.rs @@ -56,6 +56,9 @@ pub(crate) async fn token( (None, Some(url)) => url.to_string(), (None, None) => "__token__".to_string(), }; + if username.is_empty() { + bail!("Username cannot be empty"); + } let display_url = if username == "__token__" { url.without_credentials().to_string() diff --git a/crates/uv/tests/it/auth.rs b/crates/uv/tests/it/auth.rs index be52af15e..949cd4ae1 100644 --- a/crates/uv/tests/it/auth.rs +++ b/crates/uv/tests/it/auth.rs @@ -774,6 +774,38 @@ fn login_text_store() { Stored credentials for https://example.com/ " ); + + // Empty username should fail + uv_snapshot!(context.auth_login() + .arg("https://example.com/simple") + .arg("--username") + .arg("") + .arg("--password") + .arg("testpass"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: Username cannot be empty + " + ); + + // Empty password should fail + uv_snapshot!(context.auth_login() + .arg("https://example.com/simple") + .arg("--username") + .arg("testuser") + .arg("--password") + .arg(""), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: Password cannot be empty + " + ); } #[test] @@ -907,6 +939,20 @@ fn token_text_store() { ----- stderr ----- " ); + + // Empty username should fail + uv_snapshot!(context.auth_token() + .arg("https://example.com/simple") + .arg("--username") + .arg(""), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: Username cannot be empty + " + ); } #[test] @@ -957,6 +1003,20 @@ fn logout_text_store() { Removed credentials for https://example.com/ " ); + + // Empty username should fail + uv_snapshot!(context.auth_logout() + .arg("https://example.com/simple") + .arg("--username") + .arg(""), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: Username cannot be empty + " + ); } #[test]