diff --git a/cli/src/cmd_auth.rs b/cli/src/cmd_auth.rs index 2e0b1b5e..8800b9a4 100644 --- a/cli/src/cmd_auth.rs +++ b/cli/src/cmd_auth.rs @@ -497,8 +497,7 @@ impl CmdAuthStatus { { let client = Client::new_authenticated_config( &ClientConfig::default().with_host_and_token(&host_env, &token_env), - ) - .expect("client authentication from host/token failed"); + )?; spinner.set_message(format!("Checking {}...", host_env)); spinner.enable_steady_tick(Duration::from_millis(100)); @@ -521,8 +520,7 @@ impl CmdAuthStatus { let client = Client::new_authenticated_config( &ClientConfig::default() .with_host_and_token(&profile_info.host, &profile_info.token), - ) - .expect("client authentication from host/token failed"); + )?; spinner.reset(); spinner.set_message(format!("Checking {}...", &profile_info.host)); diff --git a/cli/tests/test_auth.rs b/cli/tests/test_auth.rs index de0a91c7..711f9211 100644 --- a/cli/tests/test_auth.rs +++ b/cli/tests/test_auth.rs @@ -184,14 +184,8 @@ fn test_auth_login_first() { assert_mode(&config_dir.join("config.toml"), 0o644); } -fn write_first_creds(dir: &Path) { +fn write_creds(dir: &Path, creds: &str) { let cred_path = dir.join("credentials.toml"); - let creds = "\ - [profile.first]\n\ - host = \"https://oxide.internal\"\n\ - token = \"***-***-***\"\n\ - user = \"00000000-0000-0000-0000-000000000000\"\n\ - "; write(&cred_path, creds).unwrap(); // On Unix set permissions to 0600 to avoid triggering permissions warning. @@ -204,6 +198,19 @@ fn write_first_creds(dir: &Path) { file.set_permissions(perms).unwrap(); } } + +fn write_first_creds(dir: &Path) { + write_creds( + dir, + "\ + [profile.first]\n\ + host = \"https://oxide.internal\"\n\ + token = \"***-***-***\"\n\ + user = \"00000000-0000-0000-0000-000000000000\"\n\ + ", + ); +} + fn write_first_config(dir: &Path) { let config_path = dir.join("config.toml"); let config = "\ @@ -540,6 +547,22 @@ fn test_cmd_auth_status_env() { }); }); + let temp_dir = tempfile::tempdir().unwrap(); + let temp_dir_path = temp_dir.path(); + + write_creds( + temp_dir_path, + &format!( + "\ + [profile.funky-town]\n\ + host = \"{}\"\n\ + token = \"oxide-token-good\"\n\ + user = \"00000000-0000-0000-0000-000000000000\"\n\ + ", + server.url("") + ), + ); + // Validate authenticated credentials Command::cargo_bin("oxide") .unwrap() @@ -554,7 +577,36 @@ fn test_cmd_auth_status_env() { server.url("") )); - oxide_mock.assert(); + // OXIDE_PROFILE also works, uses creds file + Command::cargo_bin("oxide") + .unwrap() + .env("OXIDE_PROFILE", "funky-town") + .arg("--config-dir") + .arg(temp_dir.path().as_os_str()) + .arg("auth") + .arg("status") + .assert() + .success() + .stdout(format!( + "Profile \"funky-town\" ({}) status: Authenticated\n", + server.url(""), + )); + + // OXIDE_HOST conflicts with OXIDE_PROFILE + Command::cargo_bin("oxide") + .unwrap() + .env("OXIDE_HOST", server.url("")) + .env("OXIDE_TOKEN", "oxide-token-good") + .env("OXIDE_PROFILE", "ignored") + .arg("--config-dir") + .arg(temp_dir.path().as_os_str()) + .arg("auth") + .arg("status") + .assert() + .failure() + .stderr(format!("{}\n", oxide::OxideAuthError::HostProfileConflict)); + + oxide_mock.assert_hits(2); let oxide_mock = server.current_user_view(|when, then| { when.into_inner() diff --git a/sdk/src/auth.rs b/sdk/src/auth.rs index 8c14204d..487227bc 100644 --- a/sdk/src/auth.rs +++ b/sdk/src/auth.rs @@ -188,6 +188,10 @@ impl Client { .. } = config; + if std::env::var("OXIDE_HOST").is_ok() && std::env::var("OXIDE_PROFILE").is_ok() { + return Err(OxideAuthError::HostProfileConflict); + } + let (host, token) = match auth_method { AuthMethod::DefaultProfile => get_profile_auth(config_dir, None)?, AuthMethod::Profile(profile) => get_profile_auth(config_dir, Some(profile))?, @@ -296,6 +300,8 @@ fn get_profile_auth( .next() .ok_or(OxideAuthError::MissingToken(env_host))? .clone() + } else if let Ok(env_profile) = std::env::var("OXIDE_PROFILE") { + env_profile } else { let config_path = config_dir.join("config.toml"); let contents = std::fs::read_to_string(&config_path).map_err(|e| { diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs index 9b6347ed..21e00604 100644 --- a/sdk/src/lib.rs +++ b/sdk/src/lib.rs @@ -37,6 +37,8 @@ pub enum OxideAuthError { Login without $OXIDE_HOST set or set $OXIDE_TOKEN." )] MissingToken(String), + #[error("Both $OXIDE_HOST and $OXIDE_PROFILE are set, only one may be used")] + HostProfileConflict, #[error("Parse error for {0}: {1}")] TomlError(PathBuf, toml::de::Error), #[error("IO Error: {0}")]