Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/cortex-cli/src/cli/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ pub async fn run_whoami() -> Result<()> {

// Check environment variables first
if let Ok(token) = std::env::var("CORTEX_AUTH_TOKEN")
&& !token.is_empty()
&& !token.trim().is_empty()
{
println!(
"Authenticated via CORTEX_AUTH_TOKEN: {}",
Expand All @@ -548,7 +548,7 @@ pub async fn run_whoami() -> Result<()> {
}

if let Ok(token) = std::env::var("CORTEX_API_KEY")
&& !token.is_empty()
&& !token.trim().is_empty()
{
println!(
"Authenticated via CORTEX_API_KEY: {}",
Expand Down
4 changes: 2 additions & 2 deletions src/cortex-cli/src/login.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ pub async fn run_login_status(config_overrides: CliConfigOverrides) -> ! {

// Check environment variables first (CORTEX_AUTH_TOKEN and CORTEX_API_KEY)
if let Ok(token) = std::env::var("CORTEX_AUTH_TOKEN")
&& !token.is_empty()
&& !token.trim().is_empty()
{
print_success(&format!(
"Authenticated via CORTEX_AUTH_TOKEN environment variable: {}",
Expand All @@ -142,7 +142,7 @@ pub async fn run_login_status(config_overrides: CliConfigOverrides) -> ! {
}

if let Ok(token) = std::env::var("CORTEX_API_KEY")
&& !token.is_empty()
&& !token.trim().is_empty()
{
print_success(&format!(
"Authenticated via CORTEX_API_KEY environment variable: {}",
Expand Down
25 changes: 19 additions & 6 deletions src/cortex-engine/src/auth_token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@

use crate::error::{CortexError, Result};

fn has_token_value(token: &str) -> bool {
!token.trim().is_empty()
}

/// Get authentication token with optional instance override.
///
/// Priority order:
Expand Down Expand Up @@ -44,15 +48,15 @@ use crate::error::{CortexError, Result};
pub fn get_auth_token(instance_token: Option<&str>) -> Result<String> {
// Priority 1: Instance token (if provided and non-empty)
if let Some(token) = instance_token {
if !token.is_empty() {
if has_token_value(token) {
tracing::debug!(source = "instance", "Using auth token from client instance");
return Ok(token.to_string());
}
}

// Priority 2: CORTEX_AUTH_TOKEN environment variable
if let Ok(token) = std::env::var("CORTEX_AUTH_TOKEN") {
if !token.is_empty() {
if has_token_value(&token) {
tracing::debug!(
source = "env_var",
"Using auth token from CORTEX_AUTH_TOKEN"
Expand All @@ -63,7 +67,7 @@ pub fn get_auth_token(instance_token: Option<&str>) -> Result<String> {

// Priority 3: CORTEX_API_KEY environment variable (alias for GitHub Actions workflow)
if let Ok(token) = std::env::var("CORTEX_API_KEY") {
if !token.is_empty() {
if has_token_value(&token) {
tracing::debug!(source = "env_var", "Using auth token from CORTEX_API_KEY");
return Ok(token);
}
Expand Down Expand Up @@ -95,17 +99,17 @@ pub fn get_auth_token_optional(instance_token: Option<&str>) -> Option<String> {
/// Useful for fast availability checks in UI.
pub fn is_authenticated(instance_token: Option<&str>) -> bool {
// Check instance token
if instance_token.map_or(false, |t| !t.is_empty()) {
if instance_token.is_some_and(has_token_value) {
return true;
}

// Check CORTEX_AUTH_TOKEN env var
if std::env::var("CORTEX_AUTH_TOKEN").map_or(false, |t| !t.is_empty()) {
if std::env::var("CORTEX_AUTH_TOKEN").is_ok_and(|t| has_token_value(&t)) {
return true;
}

// Check CORTEX_API_KEY env var (alias)
if std::env::var("CORTEX_API_KEY").map_or(false, |t| !t.is_empty()) {
if std::env::var("CORTEX_API_KEY").is_ok_and(|t| has_token_value(&t)) {
return true;
}

Expand Down Expand Up @@ -142,9 +146,18 @@ mod tests {
fn test_is_authenticated_with_instance() {
assert!(is_authenticated(Some("token")));
assert!(!is_authenticated(Some("")));
assert!(!is_authenticated(Some(" ")));
assert!(!is_authenticated(None));
}

#[test]
fn test_has_token_value_rejects_whitespace_only_tokens() {
assert!(has_token_value("token"));
assert!(!has_token_value(""));
assert!(!has_token_value(" "));
assert!(!has_token_value("\n\t"));
}

#[test]
fn test_auth_header_format() {
let header = auth_header(Some("my-token"));
Expand Down