Skip to content

Commit 9745b76

Browse files
authored
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.
1 parent 99e2324 commit 9745b76

File tree

10 files changed

+37
-2
lines changed

10 files changed

+37
-2
lines changed

crates/uv-auth/src/middleware.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,8 @@ impl Middleware for AuthMiddleware {
181181
// In the middleware, existing credentials are already moved from the URL
182182
// to the headers so for display purposes we restore some information
183183
let url = tracing_url(&request, request_credentials.as_ref());
184-
trace!("Handling request for {url}");
185-
186184
let auth_policy = self.url_auth_policies.policy_for(request.url());
185+
trace!("Handling request for {url} with authentication policy {auth_policy}");
187186

188187
let credentials: Option<Arc<Credentials>> = if matches!(auth_policy, AuthPolicy::Never) {
189188
None

crates/uv-auth/src/policy.rs

+11
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::fmt::{self, Display, Formatter};
2+
13
use rustc_hash::FxHashMap;
24
use url::Url;
35

@@ -36,6 +38,15 @@ pub enum AuthPolicy {
3638
Never,
3739
}
3840

41+
impl Display for AuthPolicy {
42+
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
43+
match self {
44+
AuthPolicy::Auto => write!(f, "auto"),
45+
AuthPolicy::Always => write!(f, "always"),
46+
AuthPolicy::Never => write!(f, "never"),
47+
}
48+
}
49+
}
3950
#[derive(Debug, Default, Clone, Eq, PartialEq)]
4051
pub struct UrlAuthPolicies(FxHashMap<Url, AuthPolicy>);
4152

crates/uv/src/commands/pip/compile.rs

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use owo_colors::OwoColorize;
1010
use rustc_hash::FxHashSet;
1111
use tracing::debug;
1212

13+
use uv_auth::UrlAuthPolicies;
1314
use uv_cache::Cache;
1415
use uv_client::{BaseClientBuilder, FlatIndexClient, RegistryClientBuilder};
1516
use uv_configuration::{
@@ -360,6 +361,7 @@ pub(crate) async fn pip_compile(
360361
.cache(cache.clone())
361362
.index_urls(index_locations.index_urls())
362363
.index_strategy(index_strategy)
364+
.url_auth_policies(UrlAuthPolicies::from(&index_locations))
363365
.torch_backend(torch_backend)
364366
.markers(interpreter.markers())
365367
.platform(interpreter.platform())

crates/uv/src/commands/pip/install.rs

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use itertools::Itertools;
77
use owo_colors::OwoColorize;
88
use tracing::{debug, enabled, Level};
99

10+
use uv_auth::UrlAuthPolicies;
1011
use uv_cache::Cache;
1112
use uv_client::{BaseClientBuilder, FlatIndexClient, RegistryClientBuilder};
1213
use uv_configuration::{
@@ -356,6 +357,7 @@ pub(crate) async fn pip_install(
356357
.cache(cache.clone())
357358
.index_urls(index_locations.index_urls())
358359
.index_strategy(index_strategy)
360+
.url_auth_policies(UrlAuthPolicies::from(&index_locations))
359361
.torch_backend(torch_backend)
360362
.markers(interpreter.markers())
361363
.platform(interpreter.platform())

crates/uv/src/commands/pip/list.rs

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use serde::Serialize;
1111
use tokio::sync::Semaphore;
1212
use unicode_width::UnicodeWidthStr;
1313

14+
use uv_auth::UrlAuthPolicies;
1415
use uv_cache::{Cache, Refresh};
1516
use uv_cache_info::Timestamp;
1617
use uv_cli::ListFormat;
@@ -90,6 +91,7 @@ pub(crate) async fn pip_list(
9091
.allow_insecure_host(network_settings.allow_insecure_host.clone())
9192
.index_urls(index_locations.index_urls())
9293
.index_strategy(index_strategy)
94+
.url_auth_policies(UrlAuthPolicies::from(&index_locations))
9395
.keyring(keyring_provider)
9496
.markers(environment.interpreter().markers())
9597
.platform(environment.interpreter().platform())

crates/uv/src/commands/pip/sync.rs

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use anyhow::Result;
66
use owo_colors::OwoColorize;
77
use tracing::debug;
88

9+
use uv_auth::UrlAuthPolicies;
910
use uv_cache::Cache;
1011
use uv_client::{BaseClientBuilder, FlatIndexClient, RegistryClientBuilder};
1112
use uv_configuration::{
@@ -284,6 +285,7 @@ pub(crate) async fn pip_sync(
284285
.cache(cache.clone())
285286
.index_urls(index_locations.index_urls())
286287
.index_strategy(index_strategy)
288+
.url_auth_policies(UrlAuthPolicies::from(&index_locations))
287289
.torch_backend(torch_backend)
288290
.markers(interpreter.markers())
289291
.platform(interpreter.platform())

crates/uv/src/commands/pip/tree.rs

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use petgraph::Direction;
1010
use rustc_hash::{FxHashMap, FxHashSet};
1111
use tokio::sync::Semaphore;
1212

13+
use uv_auth::UrlAuthPolicies;
1314
use uv_cache::{Cache, Refresh};
1415
use uv_cache_info::Timestamp;
1516
use uv_client::RegistryClientBuilder;
@@ -91,6 +92,7 @@ pub(crate) async fn pip_tree(
9192
.allow_insecure_host(network_settings.allow_insecure_host.clone())
9293
.index_urls(index_locations.index_urls())
9394
.index_strategy(index_strategy)
95+
.url_auth_policies(UrlAuthPolicies::from(&index_locations))
9496
.keyring(keyring_provider)
9597
.markers(environment.interpreter().markers())
9698
.platform(environment.interpreter().platform())

crates/uv/src/commands/project/add.rs

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_hash::{FxBuildHasher, FxHashMap};
1313
use tracing::debug;
1414
use url::Url;
1515

16+
use uv_auth::UrlAuthPolicies;
1617
use uv_cache::Cache;
1718
use uv_cache_key::RepositoryUrl;
1819
use uv_client::{BaseClientBuilder, FlatIndexClient, RegistryClientBuilder};
@@ -324,6 +325,7 @@ pub(crate) async fn add(
324325
let client = RegistryClientBuilder::try_from(client_builder)?
325326
.index_urls(settings.resolver.index_locations.index_urls())
326327
.index_strategy(settings.resolver.index_strategy)
328+
.url_auth_policies(UrlAuthPolicies::from(&settings.resolver.index_locations))
327329
.markers(target.interpreter().markers())
328330
.platform(target.interpreter().platform())
329331
.build();

crates/uv/src/commands/venv.rs

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use miette::{Diagnostic, IntoDiagnostic};
1010
use owo_colors::OwoColorize;
1111
use thiserror::Error;
1212

13+
use uv_auth::UrlAuthPolicies;
1314
use uv_cache::Cache;
1415
use uv_client::{BaseClientBuilder, FlatIndexClient, RegistryClientBuilder};
1516
use uv_configuration::{
@@ -297,6 +298,7 @@ async fn venv_impl(
297298
.cache(cache.clone())
298299
.index_urls(index_locations.index_urls())
299300
.index_strategy(index_strategy)
301+
.url_auth_policies(UrlAuthPolicies::from(index_locations))
300302
.keyring(keyring_provider)
301303
.allow_insecure_host(network_settings.allow_insecure_host.clone())
302304
.markers(interpreter.markers())

crates/uv/tests/it/edit.rs

+11
Original file line numberDiff line numberDiff line change
@@ -10134,6 +10134,17 @@ fn add_auth_policy_always_without_credentials() -> Result<()> {
1013410134
Caused by: Missing credentials for https://pypi.org/simple/anyio/
1013510135
"
1013610136
);
10137+
10138+
uv_snapshot!(context.pip_install().arg("black"), @r"
10139+
success: false
10140+
exit_code: 2
10141+
----- stdout -----
10142+
10143+
----- stderr -----
10144+
error: Failed to fetch: `https://pypi.org/simple/black/`
10145+
Caused by: Missing credentials for https://pypi.org/simple/black/
10146+
"
10147+
);
1013710148
Ok(())
1013810149
}
1013910150

0 commit comments

Comments
 (0)