mirror of
https://github.com/astral-sh/uv.git
synced 2025-10-10 02:22:08 +00:00
Allow providing the uv auth login
password or token via stdin (#15642)
This commit is contained in:
parent
63b93a1db0
commit
f9e98d1fb6
5 changed files with 105 additions and 3 deletions
|
@ -5567,12 +5567,16 @@ pub struct AuthLoginArgs {
|
|||
pub username: Option<String>,
|
||||
|
||||
/// The password to use for the service.
|
||||
///
|
||||
/// Use `-` to read the password from stdin.
|
||||
#[arg(long, conflicts_with = "token")]
|
||||
pub password: Option<String>,
|
||||
|
||||
/// The token to use for the service.
|
||||
///
|
||||
/// The username will be set to `__token__`.
|
||||
///
|
||||
/// Use `-` to read the token from stdin.
|
||||
#[arg(long, short, conflicts_with = "username", conflicts_with = "password")]
|
||||
pub token: Option<String>,
|
||||
|
||||
|
|
|
@ -87,6 +87,11 @@ pub(crate) async fn login(
|
|||
(None, Some(_), Some(_)) => {
|
||||
bail!("Cannot include a password in the URL when using `--token`")
|
||||
}
|
||||
(None, None, Some(value)) | (Some(value), None, None) if value == "-" => {
|
||||
let mut input = String::new();
|
||||
std::io::stdin().read_line(&mut input)?;
|
||||
input.trim().to_string()
|
||||
}
|
||||
(Some(cli), None, None) => cli,
|
||||
(None, Some(url), None) => url.to_string(),
|
||||
(None, None, Some(token)) => token,
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#[cfg(feature = "native-auth")]
|
||||
use anyhow::Result;
|
||||
use assert_cmd::assert::OutputAssertExt;
|
||||
#[cfg(feature = "native-auth")]
|
||||
use assert_fs::{fixture::PathChild, prelude::FileWriteStr};
|
||||
#[cfg(feature = "native-auth")]
|
||||
use uv_static::EnvVars;
|
||||
|
@ -778,6 +776,88 @@ fn login_text_store() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::disallowed_types)]
|
||||
fn login_password_stdin() -> Result<()> {
|
||||
let context = TestContext::new_with_versions(&[]);
|
||||
|
||||
// Create a temporary file with the password
|
||||
let password_file = context.temp_dir.child("password.txt");
|
||||
password_file.write_str("secret-password")?;
|
||||
|
||||
// Login with password from stdin
|
||||
uv_snapshot!(context.auth_login()
|
||||
.arg("https://example.com/simple")
|
||||
.arg("--username")
|
||||
.arg("testuser")
|
||||
.arg("--password")
|
||||
.arg("-")
|
||||
.stdin(std::fs::File::open(password_file)?), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Stored credentials for testuser@https://example.com/
|
||||
"
|
||||
);
|
||||
|
||||
// Verify the credentials work by retrieving the token
|
||||
uv_snapshot!(context.auth_token()
|
||||
.arg("https://example.com/simple")
|
||||
.arg("--username")
|
||||
.arg("testuser"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
secret-password
|
||||
|
||||
----- stderr -----
|
||||
"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::disallowed_types)]
|
||||
fn login_token_stdin() -> Result<()> {
|
||||
let context = TestContext::new_with_versions(&[]);
|
||||
|
||||
// Create a temporary file with the token
|
||||
let token_file = context.temp_dir.child("token.txt");
|
||||
token_file.write_str("secret-token")?;
|
||||
|
||||
// Login with token from stdin
|
||||
uv_snapshot!(context.auth_login()
|
||||
.arg("https://example.com/simple")
|
||||
.arg("--token")
|
||||
.arg("-")
|
||||
.stdin(std::fs::File::open(token_file)?), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Stored credentials for https://example.com/
|
||||
"
|
||||
);
|
||||
|
||||
// Verify the credentials work by retrieving the token
|
||||
uv_snapshot!(context.auth_token()
|
||||
.arg("https://example.com/simple"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
secret-token
|
||||
|
||||
----- stderr -----
|
||||
"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn token_text_store() {
|
||||
let context = TestContext::new_with_versions(&[]);
|
||||
|
|
|
@ -15,6 +15,17 @@ This will prompt for the credentials.
|
|||
The credentials can also be provided using the `--username` and `--password` options, or the
|
||||
`--token` option for services which use a `__token__` or arbitrary username.
|
||||
|
||||
!!! note
|
||||
|
||||
We recommend providing the secret via stdin. Use `-` to indicate the value should be read from
|
||||
stdin, e.g., for `--password`:
|
||||
|
||||
```console
|
||||
$ echo 'my-password' | uv auth login example.com --password -
|
||||
```
|
||||
|
||||
The same pattern can be used with `--token`.
|
||||
|
||||
Once credentials are added, uv will use them for packaging operations that require fetching content
|
||||
from the given service. At this time, only HTTPS Basic authentication is supported. The credentials
|
||||
will not yet be used for Git requests.
|
||||
|
|
|
@ -110,7 +110,8 @@ uv auth login [OPTIONS] <SERVICE>
|
|||
<p>May also be set with the <code>UV_NO_PROGRESS</code> environment variable.</p></dd><dt id="uv-auth-login--no-python-downloads"><a href="#uv-auth-login--no-python-downloads"><code>--no-python-downloads</code></a></dt><dd><p>Disable automatic downloads of Python.</p>
|
||||
</dd><dt id="uv-auth-login--offline"><a href="#uv-auth-login--offline"><code>--offline</code></a></dt><dd><p>Disable network access.</p>
|
||||
<p>When disabled, uv will only use locally cached data and locally available files.</p>
|
||||
<p>May also be set with the <code>UV_OFFLINE</code> environment variable.</p></dd><dt id="uv-auth-login--password"><a href="#uv-auth-login--password"><code>--password</code></a> <i>password</i></dt><dd><p>The password to use for the service</p>
|
||||
<p>May also be set with the <code>UV_OFFLINE</code> environment variable.</p></dd><dt id="uv-auth-login--password"><a href="#uv-auth-login--password"><code>--password</code></a> <i>password</i></dt><dd><p>The password to use for the service.</p>
|
||||
<p>Use <code>-</code> to read the password from stdin.</p>
|
||||
</dd><dt id="uv-auth-login--project"><a href="#uv-auth-login--project"><code>--project</code></a> <i>project</i></dt><dd><p>Run the command within the given project directory.</p>
|
||||
<p>All <code>pyproject.toml</code>, <code>uv.toml</code>, and <code>.python-version</code> files will be discovered by walking up the directory tree from the project root, as will the project's virtual environment (<code>.venv</code>).</p>
|
||||
<p>Other command-line arguments (such as relative paths) will be resolved relative to the current working directory.</p>
|
||||
|
@ -120,6 +121,7 @@ uv auth login [OPTIONS] <SERVICE>
|
|||
<p>Repeating this option, e.g., <code>-qq</code>, will enable a silent mode in which uv will write no output to stdout.</p>
|
||||
</dd><dt id="uv-auth-login--token"><a href="#uv-auth-login--token"><code>--token</code></a>, <code>-t</code> <i>token</i></dt><dd><p>The token to use for the service.</p>
|
||||
<p>The username will be set to <code>__token__</code>.</p>
|
||||
<p>Use <code>-</code> to read the token from stdin.</p>
|
||||
</dd><dt id="uv-auth-login--username"><a href="#uv-auth-login--username"><code>--username</code></a>, <code>-u</code> <i>username</i></dt><dd><p>The username to use for the service</p>
|
||||
</dd><dt id="uv-auth-login--verbose"><a href="#uv-auth-login--verbose"><code>--verbose</code></a>, <code>-v</code></dt><dd><p>Use verbose output.</p>
|
||||
<p>You can configure fine-grained logging using the <code>RUST_LOG</code> environment variable. (<a href="https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives">https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives</a>)</p>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue