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:
1 parent
c1d32b4181
commit
b0d70b390a
2 files changed
+43
-3
No files matched your search
@@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
||||||
|
}
|
||||||
|
|
||||||
Reference in new issue
Block a user