-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Distinguish between authentication failures due to missing vs invalid credentials #12667
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7517,16 +7517,15 @@ fn lock_index_workspace_member() -> Result<()> { | |
| )?; | ||
|
|
||
| // Locking without the necessary credentials should fail. | ||
| uv_snapshot!(context.filters(), context.lock(), @r###" | ||
| uv_snapshot!(context.filters(), context.lock(), @r" | ||
| success: false | ||
| exit_code: 1 | ||
| exit_code: 2 | ||
| ----- stdout ----- | ||
|
|
||
| ----- stderr ----- | ||
| × No solution found when resolving dependencies: | ||
| ╰─▶ Because iniconfig was not found in the package registry and child depends on iniconfig>=2, we can conclude that child's requirements are unsatisfiable. | ||
| And because your workspace requires child, we can conclude that your workspace's requirements are unsatisfiable. | ||
| "###); | ||
| error: Failed to fetch: `https://pypi-proxy.fly.dev/basic-auth/simple/iniconfig/` | ||
| Caused by: Missing credentials for https://pypi-proxy.fly.dev/basic-auth/simple/iniconfig/ | ||
| "); | ||
|
Comment on lines
-7520
to
+7528
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A bit of an aside, but... why weren't we showing the hint from https://github.com/astral-sh/uv/pull/12667/files#diff-82edd36151736f44055f699a34c8b19a63ffc4cf3c86bf5fb34d69f8ac88a957L8471 in this case?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's a good question. I'll look into it |
||
|
|
||
| uv_snapshot!(context.filters(), context.lock() | ||
| .env("UV_INDEX_MY_INDEX_USERNAME", "public") | ||
|
|
@@ -7870,30 +7869,30 @@ fn lock_redact_https() -> Result<()> { | |
|
|
||
| // Installing from the lockfile should fail without credentials. Omit the root, so that we fail | ||
| // when installing `iniconfig`, rather than when building `foo`. | ||
| uv_snapshot!(context.filters(), context.sync().arg("--frozen").arg("--index-url").arg("https://pypi-proxy.fly.dev/basic-auth/simple").arg("--no-install-project"), @r###" | ||
| uv_snapshot!(context.filters(), context.sync().arg("--frozen").arg("--index-url").arg("https://pypi-proxy.fly.dev/basic-auth/simple").arg("--no-install-project"), @r" | ||
| success: false | ||
| exit_code: 1 | ||
| ----- stdout ----- | ||
|
|
||
| ----- stderr ----- | ||
| × Failed to download `iniconfig==2.0.0` | ||
| ├─▶ Failed to fetch: `https://pypi-proxy.fly.dev/basic-auth/files/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl` | ||
| ╰─▶ HTTP status client error (401 Unauthorized) for url (https://pypi-proxy.fly.dev/basic-auth/files/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl) | ||
| ╰─▶ Missing credentials for https://pypi-proxy.fly.dev/basic-auth/files/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl | ||
| help: `iniconfig` (v2.0.0) was included because `foo` (v0.1.0) depends on `iniconfig` | ||
| "###); | ||
| "); | ||
|
|
||
| // Installing from the lockfile should fail without an index. | ||
| uv_snapshot!(context.filters(), context.sync().arg("--frozen").arg("--no-install-project"), @r###" | ||
| uv_snapshot!(context.filters(), context.sync().arg("--frozen").arg("--no-install-project"), @r" | ||
| success: false | ||
| exit_code: 1 | ||
| ----- stdout ----- | ||
|
|
||
| ----- stderr ----- | ||
| × Failed to download `iniconfig==2.0.0` | ||
| ├─▶ Failed to fetch: `https://pypi-proxy.fly.dev/basic-auth/files/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl` | ||
| ╰─▶ HTTP status client error (401 Unauthorized) for url (https://pypi-proxy.fly.dev/basic-auth/files/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl) | ||
| ╰─▶ Missing credentials for https://pypi-proxy.fly.dev/basic-auth/files/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl | ||
| help: `iniconfig` (v2.0.0) was included because `foo` (v0.1.0) depends on `iniconfig` | ||
| "###); | ||
| "); | ||
|
|
||
| // Installing from the lockfile should succeed when credentials are included on the command-line. | ||
| uv_snapshot!(context.filters(), context.sync().arg("--frozen").arg("--index-url").arg("https://public:heron@pypi-proxy.fly.dev/basic-auth/simple"), @r###" | ||
|
|
@@ -7921,17 +7920,17 @@ fn lock_redact_https() -> Result<()> { | |
| "###); | ||
|
|
||
| // Installing without credentials will fail without a cache. | ||
| uv_snapshot!(context.filters(), context.sync().arg("--frozen").arg("--reinstall").arg("--no-cache").arg("--no-install-project"), @r###" | ||
| uv_snapshot!(context.filters(), context.sync().arg("--frozen").arg("--reinstall").arg("--no-cache").arg("--no-install-project"), @r" | ||
| success: false | ||
| exit_code: 1 | ||
| ----- stdout ----- | ||
|
|
||
| ----- stderr ----- | ||
| × Failed to download `iniconfig==2.0.0` | ||
| ├─▶ Failed to fetch: `https://pypi-proxy.fly.dev/basic-auth/files/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl` | ||
| ╰─▶ HTTP status client error (401 Unauthorized) for url (https://pypi-proxy.fly.dev/basic-auth/files/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl) | ||
| ╰─▶ Missing credentials for https://pypi-proxy.fly.dev/basic-auth/files/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl | ||
| help: `iniconfig` (v2.0.0) was included because `foo` (v0.1.0) depends on `iniconfig` | ||
| "###); | ||
| "); | ||
|
|
||
| // Installing with credentials from with `UV_INDEX_URL` should succeed. | ||
| uv_snapshot!(context.filters(), context.sync().arg("--frozen").arg("--reinstall").arg("--no-cache").env(EnvVars::UV_INDEX_URL, "https://public:heron@pypi-proxy.fly.dev/basic-auth/simple"), @r###" | ||
|
|
@@ -8459,17 +8458,15 @@ fn lock_env_credentials() -> Result<()> { | |
| )?; | ||
|
|
||
| // Without credentials, the resolution should fail. | ||
| uv_snapshot!(context.filters(), context.lock(), @r###" | ||
| uv_snapshot!(context.filters(), context.lock(), @r" | ||
| success: false | ||
| exit_code: 1 | ||
| exit_code: 2 | ||
| ----- stdout ----- | ||
|
|
||
| ----- stderr ----- | ||
| × No solution found when resolving dependencies: | ||
| ╰─▶ Because iniconfig was not found in the package registry and your project depends on iniconfig, we can conclude that your project's requirements are unsatisfiable. | ||
|
|
||
| hint: An index URL (https://pypi-proxy.fly.dev/basic-auth/simple) could not be queried due to a lack of valid authentication credentials (401 Unauthorized). | ||
| "###); | ||
| error: Failed to fetch: `https://pypi-proxy.fly.dev/basic-auth/simple/iniconfig/` | ||
| Caused by: Missing credentials for https://pypi-proxy.fly.dev/basic-auth/simple/iniconfig/ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks like a regression to me?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a case where the fetch failed because there were no credentials, which is the reason the package was not found (since we were never authenticated, we were not able to search for it). So this case is intentional. Does it still seem like a regression?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think so? Doesn't this fail eagerly now? What if there was a second index with the package available?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (It should be easy to add a test for that, we should probably have coverage regardless)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll add that test. |
||
| "); | ||
|
|
||
| // Provide credentials via environment variables. | ||
| uv_snapshot!(context.filters(), context.lock() | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did this one change? There's no policy set here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe there's a better way to do it, but the existing approach had been to throw an error for the missing credentials case. There's no policy set here, but the reason for the 401 is because of missing credentials.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we can throw an error there though, doesn't downstream logic rely on a successful request? (i.e., in #12667 (comment))
Perhaps I misunderstood the intent of this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only tests that broke were cases where we'd want the message to indicate that missing credentials was the cause of failing to find the package. But if we are depending on getting the 401 out of this response downstream, then this approach won't work. In that case, I can try using reqwest extensions to add more context about the 401.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I understand the goal now, you want to make the case where no credentials were present distinct from the case where the credentials are wrong. Sorry it took me a while to get there. I think the snapshot changes should be like..
to
and
I think changing that error path entirely feels too risky and is hopefully unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(fwiw, I think this would have been clearer if the title was something like "Distinguish between authentication failures due to missing vs invalid credentials")