mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 21:35:00 +00:00
Add integration test coverage for keyring authentication (#3067)
Closes https://github.com/astral-sh/uv/issues/2464
This commit is contained in:
parent
e5d4ea55ca
commit
7c5b13c412
5 changed files with 178 additions and 1 deletions
|
@ -309,6 +309,16 @@ fn site_packages_path(venv: &Path, python: String) -> PathBuf {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn venv_bin_path(venv: &Path) -> PathBuf {
|
||||||
|
if cfg!(unix) {
|
||||||
|
venv.join("bin")
|
||||||
|
} else if cfg!(windows) {
|
||||||
|
venv.join("Scripts")
|
||||||
|
} else {
|
||||||
|
unimplemented!("Only Windows and Unix are supported")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn venv_to_interpreter(venv: &Path) -> PathBuf {
|
pub fn venv_to_interpreter(venv: &Path) -> PathBuf {
|
||||||
if cfg!(unix) {
|
if cfg!(unix) {
|
||||||
venv.join("bin").join("python")
|
venv.join("bin").join("python")
|
||||||
|
|
|
@ -12,7 +12,7 @@ use itertools::Itertools;
|
||||||
use common::{uv_snapshot, TestContext};
|
use common::{uv_snapshot, TestContext};
|
||||||
use uv_fs::Simplified;
|
use uv_fs::Simplified;
|
||||||
|
|
||||||
use crate::common::{get_bin, BUILD_VENDOR_LINKS_URL};
|
use crate::common::{get_bin, venv_bin_path, BUILD_VENDOR_LINKS_URL};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
|
@ -2916,6 +2916,128 @@ fn install_index_with_relative_links() {
|
||||||
context.assert_command("import anyio").success();
|
context.assert_command("import anyio").success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Install a package from an index that requires authentication from the keyring.
|
||||||
|
#[test]
|
||||||
|
fn install_package_basic_auth_from_keyring() {
|
||||||
|
let context = TestContext::new("3.12");
|
||||||
|
|
||||||
|
// Install our keyring plugin
|
||||||
|
context
|
||||||
|
.install()
|
||||||
|
.arg(
|
||||||
|
context
|
||||||
|
.workspace_root
|
||||||
|
.join("scripts")
|
||||||
|
.join("packages")
|
||||||
|
.join("keyring_test_plugin"),
|
||||||
|
)
|
||||||
|
.assert()
|
||||||
|
.success();
|
||||||
|
|
||||||
|
uv_snapshot!(context.install()
|
||||||
|
.arg("anyio")
|
||||||
|
.arg("--index-url")
|
||||||
|
.arg("https://public@pypi-proxy.fly.dev/basic-auth/simple")
|
||||||
|
.arg("--keyring-provider")
|
||||||
|
.arg("subprocess")
|
||||||
|
.arg("--strict")
|
||||||
|
.env("KEYRING_TEST_CREDENTIALS", r#"{"pypi-proxy.fly.dev": {"public": "heron"}}"#)
|
||||||
|
.env("PATH", venv_bin_path(context.venv.as_path())), @r###"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Resolved 3 packages in [TIME]
|
||||||
|
Downloaded 3 packages in [TIME]
|
||||||
|
Installed 3 packages in [TIME]
|
||||||
|
+ anyio==4.3.0
|
||||||
|
+ idna==3.6
|
||||||
|
+ sniffio==1.3.1
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
|
||||||
|
context.assert_command("import anyio").success();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Install a package from an index that requires authentication
|
||||||
|
/// but the keyring has the wrong password
|
||||||
|
#[test]
|
||||||
|
fn install_package_basic_auth_from_keyring_wrong_password() {
|
||||||
|
let context = TestContext::new("3.12");
|
||||||
|
|
||||||
|
// Install our keyring plugin
|
||||||
|
context
|
||||||
|
.install()
|
||||||
|
.arg(
|
||||||
|
context
|
||||||
|
.workspace_root
|
||||||
|
.join("scripts")
|
||||||
|
.join("packages")
|
||||||
|
.join("keyring_test_plugin"),
|
||||||
|
)
|
||||||
|
.assert()
|
||||||
|
.success();
|
||||||
|
|
||||||
|
uv_snapshot!(context.install()
|
||||||
|
.arg("anyio")
|
||||||
|
.arg("--index-url")
|
||||||
|
.arg("https://public@pypi-proxy.fly.dev/basic-auth/simple")
|
||||||
|
.arg("--keyring-provider")
|
||||||
|
.arg("subprocess")
|
||||||
|
.arg("--strict")
|
||||||
|
.env("KEYRING_TEST_CREDENTIALS", r#"{"pypi-proxy.fly.dev": {"public": "foobar"}}"#)
|
||||||
|
.env("PATH", venv_bin_path(context.venv.as_path())), @r###"
|
||||||
|
success: false
|
||||||
|
exit_code: 2
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
error: Failed to download: anyio==4.3.0
|
||||||
|
Caused by: HTTP status client error (401 Unauthorized) for url (https://pypi-proxy.fly.dev/basic-auth/files/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl.metadata)
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Install a package from an index that requires authentication
|
||||||
|
/// but the keyring has the wrong username
|
||||||
|
#[test]
|
||||||
|
fn install_package_basic_auth_from_keyring_wrong_username() {
|
||||||
|
let context = TestContext::new("3.12");
|
||||||
|
|
||||||
|
// Install our keyring plugin
|
||||||
|
context
|
||||||
|
.install()
|
||||||
|
.arg(
|
||||||
|
context
|
||||||
|
.workspace_root
|
||||||
|
.join("scripts")
|
||||||
|
.join("packages")
|
||||||
|
.join("keyring_test_plugin"),
|
||||||
|
)
|
||||||
|
.assert()
|
||||||
|
.success();
|
||||||
|
|
||||||
|
uv_snapshot!(context.install()
|
||||||
|
.arg("anyio")
|
||||||
|
.arg("--index-url")
|
||||||
|
.arg("https://public@pypi-proxy.fly.dev/basic-auth/simple")
|
||||||
|
.arg("--keyring-provider")
|
||||||
|
.arg("subprocess")
|
||||||
|
.arg("--strict")
|
||||||
|
.env("KEYRING_TEST_CREDENTIALS", r#"{"pypi-proxy.fly.dev": {"other": "heron"}}"#)
|
||||||
|
.env("PATH", venv_bin_path(context.venv.as_path())), @r###"
|
||||||
|
success: false
|
||||||
|
exit_code: 2
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
error: Failed to download: anyio==4.3.0
|
||||||
|
Caused by: HTTP status client error (401 Unauthorized) for url (https://pypi-proxy.fly.dev/basic-auth/files/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl.metadata)
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// Install a package from an index that provides relative links and requires authentication
|
/// Install a package from an index that provides relative links and requires authentication
|
||||||
#[test]
|
#[test]
|
||||||
fn install_index_with_relative_links_authenticated() {
|
fn install_index_with_relative_links_authenticated() {
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from keyring import backend
|
||||||
|
|
||||||
|
|
||||||
|
class KeyringTest(backend.KeyringBackend):
|
||||||
|
priority = 9
|
||||||
|
|
||||||
|
def get_password(self, service, username):
|
||||||
|
print(f"Request for {username}@{service}", file=sys.stderr)
|
||||||
|
credentials = json.loads(os.environ.get("KEYRING_TEST_CREDENTIALS") or {})
|
||||||
|
return credentials.get(service, {}).get(username)
|
||||||
|
|
||||||
|
def set_password(self, service, username, password):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def delete_password(self, service, username):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def get_credential(self, service, username):
|
||||||
|
raise NotImplementedError()
|
22
scripts/packages/keyring_test_plugin/pyproject.toml
Normal file
22
scripts/packages/keyring_test_plugin/pyproject.toml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
[build-system]
|
||||||
|
requires = ["flit_core >=3.2,<4"]
|
||||||
|
build-backend = "flit_core.buildapi"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "keyring-test-plugin"
|
||||||
|
description = "A keyring plugin for testing."
|
||||||
|
requires-python = ">=3.7"
|
||||||
|
version = "0.1.0"
|
||||||
|
keywords = []
|
||||||
|
authors = [
|
||||||
|
{ name = "Astral Software Inc.", email = "hey@astral.sh" },
|
||||||
|
]
|
||||||
|
dependencies = [
|
||||||
|
"keyring"
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.flit.module]
|
||||||
|
name = "keyrings"
|
||||||
|
|
||||||
|
[project.entry-points."keyring.backends"]
|
||||||
|
AstralTest = "keyrings.test_keyring"
|
Loading…
Add table
Add a link
Reference in a new issue