Add auth policy support for pip commands (#12470)
We were not applying the `authenticate = "always"` behavior to `uv pip` commands (related to #12362). This PR addresses that, applying authentication policies wherever we set up a registry client.
This commit is contained in:
@@ -181,9 +181,8 @@ impl Middleware for AuthMiddleware {
|
||||
// In the middleware, existing credentials are already moved from the URL
|
||||
// to the headers so for display purposes we restore some information
|
||||
let url = tracing_url(&request, request_credentials.as_ref());
|
||||
trace!("Handling request for {url}");
|
||||
|
||||
let auth_policy = self.url_auth_policies.policy_for(request.url());
|
||||
trace!("Handling request for {url} with authentication policy {auth_policy}");
|
||||
|
||||
let credentials: Option<Arc<Credentials>> = if matches!(auth_policy, AuthPolicy::Never) {
|
||||
None
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
|
||||
use rustc_hash::FxHashMap;
|
||||
use url::Url;
|
||||
|
||||
@@ -36,6 +38,15 @@ pub enum AuthPolicy {
|
||||
Never,
|
||||
}
|
||||
|
||||
impl Display for AuthPolicy {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
match self {
|
||||
AuthPolicy::Auto => write!(f, "auto"),
|
||||
AuthPolicy::Always => write!(f, "always"),
|
||||
AuthPolicy::Never => write!(f, "never"),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Default, Clone, Eq, PartialEq)]
|
||||
pub struct UrlAuthPolicies(FxHashMap<Url, AuthPolicy>);
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ use owo_colors::OwoColorize;
|
||||
use rustc_hash::FxHashSet;
|
||||
use tracing::debug;
|
||||
|
||||
use uv_auth::UrlAuthPolicies;
|
||||
use uv_cache::Cache;
|
||||
use uv_client::{BaseClientBuilder, FlatIndexClient, RegistryClientBuilder};
|
||||
use uv_configuration::{
|
||||
@@ -360,6 +361,7 @@ pub(crate) async fn pip_compile(
|
||||
.cache(cache.clone())
|
||||
.index_urls(index_locations.index_urls())
|
||||
.index_strategy(index_strategy)
|
||||
.url_auth_policies(UrlAuthPolicies::from(&index_locations))
|
||||
.torch_backend(torch_backend)
|
||||
.markers(interpreter.markers())
|
||||
.platform(interpreter.platform())
|
||||
|
||||
@@ -7,6 +7,7 @@ use itertools::Itertools;
|
||||
use owo_colors::OwoColorize;
|
||||
use tracing::{debug, enabled, Level};
|
||||
|
||||
use uv_auth::UrlAuthPolicies;
|
||||
use uv_cache::Cache;
|
||||
use uv_client::{BaseClientBuilder, FlatIndexClient, RegistryClientBuilder};
|
||||
use uv_configuration::{
|
||||
@@ -356,6 +357,7 @@ pub(crate) async fn pip_install(
|
||||
.cache(cache.clone())
|
||||
.index_urls(index_locations.index_urls())
|
||||
.index_strategy(index_strategy)
|
||||
.url_auth_policies(UrlAuthPolicies::from(&index_locations))
|
||||
.torch_backend(torch_backend)
|
||||
.markers(interpreter.markers())
|
||||
.platform(interpreter.platform())
|
||||
|
||||
@@ -11,6 +11,7 @@ use serde::Serialize;
|
||||
use tokio::sync::Semaphore;
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
use uv_auth::UrlAuthPolicies;
|
||||
use uv_cache::{Cache, Refresh};
|
||||
use uv_cache_info::Timestamp;
|
||||
use uv_cli::ListFormat;
|
||||
@@ -90,6 +91,7 @@ pub(crate) async fn pip_list(
|
||||
.allow_insecure_host(network_settings.allow_insecure_host.clone())
|
||||
.index_urls(index_locations.index_urls())
|
||||
.index_strategy(index_strategy)
|
||||
.url_auth_policies(UrlAuthPolicies::from(&index_locations))
|
||||
.keyring(keyring_provider)
|
||||
.markers(environment.interpreter().markers())
|
||||
.platform(environment.interpreter().platform())
|
||||
|
||||
@@ -6,6 +6,7 @@ use anyhow::Result;
|
||||
use owo_colors::OwoColorize;
|
||||
use tracing::debug;
|
||||
|
||||
use uv_auth::UrlAuthPolicies;
|
||||
use uv_cache::Cache;
|
||||
use uv_client::{BaseClientBuilder, FlatIndexClient, RegistryClientBuilder};
|
||||
use uv_configuration::{
|
||||
@@ -284,6 +285,7 @@ pub(crate) async fn pip_sync(
|
||||
.cache(cache.clone())
|
||||
.index_urls(index_locations.index_urls())
|
||||
.index_strategy(index_strategy)
|
||||
.url_auth_policies(UrlAuthPolicies::from(&index_locations))
|
||||
.torch_backend(torch_backend)
|
||||
.markers(interpreter.markers())
|
||||
.platform(interpreter.platform())
|
||||
|
||||
@@ -10,6 +10,7 @@ use petgraph::Direction;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use tokio::sync::Semaphore;
|
||||
|
||||
use uv_auth::UrlAuthPolicies;
|
||||
use uv_cache::{Cache, Refresh};
|
||||
use uv_cache_info::Timestamp;
|
||||
use uv_client::RegistryClientBuilder;
|
||||
@@ -91,6 +92,7 @@ pub(crate) async fn pip_tree(
|
||||
.allow_insecure_host(network_settings.allow_insecure_host.clone())
|
||||
.index_urls(index_locations.index_urls())
|
||||
.index_strategy(index_strategy)
|
||||
.url_auth_policies(UrlAuthPolicies::from(&index_locations))
|
||||
.keyring(keyring_provider)
|
||||
.markers(environment.interpreter().markers())
|
||||
.platform(environment.interpreter().platform())
|
||||
|
||||
@@ -13,6 +13,7 @@ use rustc_hash::{FxBuildHasher, FxHashMap};
|
||||
use tracing::debug;
|
||||
use url::Url;
|
||||
|
||||
use uv_auth::UrlAuthPolicies;
|
||||
use uv_cache::Cache;
|
||||
use uv_cache_key::RepositoryUrl;
|
||||
use uv_client::{BaseClientBuilder, FlatIndexClient, RegistryClientBuilder};
|
||||
@@ -324,6 +325,7 @@ pub(crate) async fn add(
|
||||
let client = RegistryClientBuilder::try_from(client_builder)?
|
||||
.index_urls(settings.resolver.index_locations.index_urls())
|
||||
.index_strategy(settings.resolver.index_strategy)
|
||||
.url_auth_policies(UrlAuthPolicies::from(&settings.resolver.index_locations))
|
||||
.markers(target.interpreter().markers())
|
||||
.platform(target.interpreter().platform())
|
||||
.build();
|
||||
|
||||
@@ -10,6 +10,7 @@ use miette::{Diagnostic, IntoDiagnostic};
|
||||
use owo_colors::OwoColorize;
|
||||
use thiserror::Error;
|
||||
|
||||
use uv_auth::UrlAuthPolicies;
|
||||
use uv_cache::Cache;
|
||||
use uv_client::{BaseClientBuilder, FlatIndexClient, RegistryClientBuilder};
|
||||
use uv_configuration::{
|
||||
@@ -297,6 +298,7 @@ async fn venv_impl(
|
||||
.cache(cache.clone())
|
||||
.index_urls(index_locations.index_urls())
|
||||
.index_strategy(index_strategy)
|
||||
.url_auth_policies(UrlAuthPolicies::from(index_locations))
|
||||
.keyring(keyring_provider)
|
||||
.allow_insecure_host(network_settings.allow_insecure_host.clone())
|
||||
.markers(interpreter.markers())
|
||||
|
||||
@@ -10134,6 +10134,17 @@ fn add_auth_policy_always_without_credentials() -> Result<()> {
|
||||
Caused by: Missing credentials for https://pypi.org/simple/anyio/
|
||||
"
|
||||
);
|
||||
|
||||
uv_snapshot!(context.pip_install().arg("black"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: Failed to fetch: `https://pypi.org/simple/black/`
|
||||
Caused by: Missing credentials for https://pypi.org/simple/black/
|
||||
"
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user