rust-lang / cargo

The Rust package manager
https://doc.rust-lang.org/cargo
Apache License 2.0
12.78k stars 2.42k forks source link

When using env variable for alternative registry index, token retrieval from credentials does not handle hyphens/underscores correctly #11737

Open pnevyk opened 1 year ago

pnevyk commented 1 year ago

Problem

When the alternative registry index is specified via environment variable (e.g., CARGO_REGISTRIES_MY_REGISTRY_INDEX), then retrieving the token from .cargo/credentials{,.toml} does not handle hyphen/underscore interchangeability in the registry name. It tries to load the token from registries.my_registry section, while it should load it from registries.my-registry if the hyphenated name was used for login.

Steps

  1. Create a project that depends on/publishes into an alternative registry with a multi-word name (e.g., my-registry).
  2. Specify the index via the environment variable (e.g., CARGO_REGISTRIES_MY_REGISTRY_INDEX).
  3. Run cargo login --registry my-registry and input the token. This saves the token to the credentials file under registries.my-registry section.
  4. Run a cargo command (e.g., build) that requires authentication for the registry. It fails with the error below:
error: no token found for `my-registry`, please run `cargo login --registry my-registry`
or use environment variable CARGO_REGISTRIES_MY_REGISTRY_TOKEN

This is caused by the fact that the code retrieving the index name takes the name of the environment variable and only strips prefix and suffix and makes it lowercase. Such extracted name is then used for trying to get the token. However, there is a mismatch between my_registry and my-registry, causing cargo to think there is no token for the registry.

Possible Solution(s)

I have a working fix that compares the name with the alternative registry key of the source ID (if available) here, and if I detect that these are equal except hyphens and underscores, I reassign the name to be the alternative registry key instead. It works for the case I described above, but I don't know if there isn't a case when this would fail because of alternative registry key being absent.

If this solution is a good start, I can open a PR.

Notes

Before the error cargo also gives this note (notice use of underscore instead of hyphen):

note: name of alternative registry `[..]` set to `my_registry`

The cargo login command also gives suspicious logs:

note: name of alternative registry `[..]` set to `my_registry`
    Updating `my-registry` index
note: name of alternative registry `[..]` set to `my_registry`
       Login token for `my-registry` saved

Version

cargo 1.67.1 (8ecd4f20a 2023-01-10)
release: 1.67.1
commit-hash: 8ecd4f20a9efb626975ac18a016d480dc7183d9b
commit-date: 2023-01-10
host: x86_64-unknown-linux-gnu
libgit2: 1.5.0 (sys:0.16.0 vendored)
libcurl: 7.86.0-DEV (sys:0.4.59+curl-7.86.0 vendored ssl:OpenSSL/1.1.1q)
os: Linux [64-bit]
pnevyk commented 1 year ago

Just for reference, using the environment variable for token (CARGO_REGISTRIES_MY_REGISTRY_TOKEN) works.