Security: Remove email from credential logs and add live smoke test

credentials/mod.rs:
- Remove email from log messages (privacy/security best practice)
- Logs still indicate success without exposing PII

tests/qobuz_live_smoke.rs:
- Add ignored live smoke test for Qobuz API
- Requires explicit opt-in via QBZ_RUN_QOBUZ_LIVE_TESTS=1
- Uses local credentials from keyring (no hardcoded secrets)
- Basic test: login + get_favorites endpoint
- Safe for repository (no credentials exposed)
This commit is contained in:
vicrodh committed 2026-01-20 14:07:52 -06:00
1 parent c1d32b4181
commit b0d70b390a
2 files changed
+43 -3

No files matched your search

+3 -3
View File
@@ -85,7 +85,7 @@ fn load_from_fallback() -> Result<Option<QobuzCredentials>, String> {
let credentials: QobuzCredentials = serde_json::from_str(&json) let credentials: QobuzCredentials = serde_json::from_str(&json)
.map_err(|e| format!("Failed to parse credentials: {}", e))?; .map_err(|e| format!("Failed to parse credentials: {}", e))?;
log::info!("Credentials loaded from fallback file for: {}", credentials.email); log::info!("Credentials loaded from fallback file");
Ok(Some(credentials)) Ok(Some(credentials))
} }
@@ -108,7 +108,7 @@ fn has_fallback_credentials() -> bool {
/// Save Qobuz credentials - saves to both file (primary) and keyring (secondary) /// Save Qobuz credentials - saves to both file (primary) and keyring (secondary)
pub fn save_qobuz_credentials(email: &str, password: &str) -> Result<(), String> { pub fn save_qobuz_credentials(email: &str, password: &str) -> Result<(), String> {
log::info!("Attempting to save credentials for: {}", email); log::info!("Attempting to save credentials");
let credentials = QobuzCredentials { let credentials = QobuzCredentials {
email: email.to_string(), email: email.to_string(),
@@ -140,7 +140,7 @@ pub fn load_qobuz_credentials() -> Result<Option<QobuzCredentials>, String> {
match entry.get_password() { match entry.get_password() {
Ok(json) => { Ok(json) => {
if let Ok(credentials) = serde_json::from_str::<QobuzCredentials>(&json) { if let Ok(credentials) = serde_json::from_str::<QobuzCredentials>(&json) {
log::info!("Successfully loaded credentials from keyring for: {}", credentials.email); log::info!("Successfully loaded credentials from keyring");
return Ok(Some(credentials)); return Ok(Some(credentials));
} }
} }
+40
View File
@@ -0,0 +1,40 @@
use qbz_nix_lib::{api::QobuzClient, credentials};
// Live tests against Qobuz require:
// - Explicit opt-in via env var
// - Local credentials available via QBZ credential store (keyring or fallback file)
//
// These tests must never print credentials or tokens.
fn live_tests_enabled() -> bool {
matches!(std::env::var("QBZ_RUN_QOBUZ_LIVE_TESTS").as_deref(), Ok("1"))
}
#[tokio::test]
#[ignore]
async fn qobuz_login_and_favorites_smoke() {
if !live_tests_enabled() {
return;
}
let Some(creds) = credentials::load_qobuz_credentials()
.expect("Failed to load credentials")
else {
return;
};
let client = QobuzClient::default();
client.init().await.expect("Failed to init client");
client
.login(&creds.email, &creds.password)
.await
.expect("Login failed");
// Auth + signature protected endpoint; should succeed even if empty.
let _ = client
.get_favorites("tracks", 1, 0)
.await
.expect("get_favorites failed");
}