mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-09-02 01:29:23 +00:00
refactor: centralize test credential constants into testing::credentials (#829)
* refactor: centralize test credential constants into testing::credentials Scattered test credential strings (API keys, OAuth tokens, crypto keys, Telegram tokens, session tokens) across ~25 files made security auditing harder and created unnecessary duplication. Centralize all test-only fake credentials into a new `src/testing/credentials.rs` module with named constants and a shared `test_secrets_store()` helper. - Convert `src/testing.rs` to directory module (`src/testing/mod.rs`) - Add `src/testing/credentials.rs` with ~30 named constants - Replace hardcoded literals in 24 source files - Deduplicate `test_store()` helper (was copy-pasted in 3 files) - Leave leak_detector/shell/signature tests as-is (inline values aid readability for pattern detection tests) [skip-regression-check] Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * refactor: replace real Telegram bot token with obviously fake test stub Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * Update src/testing/credentials.rs Co-authored-by: Copilot <[email protected]> * Update src/testing/credentials.rs Co-authored-by: Copilot <[email protected]> * refactor: address PR review feedback on test credentials - Fix TEST_CRYPTO_KEY doc comment ("32-byte hex" → "32-character key string") - Rename confusing "real"/"fake" Anthropic constant names and values - Change TEST_STRIPE_KEY from "sk-live" to "sk_test_fake123" to avoid scanners - Use test_secrets_store() helper in orchestrator and http tool tests - Clarify config_round_trip.rs doc comment about integration test visibility Co-Authored-By: Claude Opus 4.6 <[email protected]> --------- Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]> Co-authored-by: Copilot <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.6
Copilot
parent
24d4fbb8a7
commit
76375f2eaa
@@ -365,6 +365,7 @@ pub trait ChannelSecretUpdater: Send + Sync {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::testing::credentials::TEST_REDACT_SECRET_123;
|
||||
|
||||
/// Stub tool that marks `"value"` as sensitive.
|
||||
struct SecretTool;
|
||||
@@ -394,7 +395,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn tool_completed_redacts_sensitive_params_on_failure() {
|
||||
let params = serde_json::json!({"name": "api_key", "value": "sk-secret-123"});
|
||||
let params = serde_json::json!({"name": "api_key", "value": TEST_REDACT_SECRET_123});
|
||||
let err: Result<String, crate::error::Error> =
|
||||
Err(crate::error::ToolError::ExecutionFailed {
|
||||
name: "secret_save".into(),
|
||||
@@ -429,7 +430,7 @@ mod tests {
|
||||
param_str
|
||||
);
|
||||
assert!(
|
||||
!param_str.contains("sk-secret-123"),
|
||||
!param_str.contains(TEST_REDACT_SECRET_123),
|
||||
"raw secret should not appear: {}",
|
||||
param_str
|
||||
);
|
||||
|
||||
@@ -3059,6 +3059,7 @@ mod tests {
|
||||
};
|
||||
use crate::channels::wasm::wrapper::{HttpResponse, WasmChannel};
|
||||
use crate::pairing::PairingStore;
|
||||
use crate::testing::credentials::TEST_TELEGRAM_BOT_TOKEN;
|
||||
use crate::tools::wasm::ResourceLimits;
|
||||
|
||||
fn create_test_channel() -> WasmChannel {
|
||||
@@ -4009,7 +4010,7 @@ mod tests {
|
||||
let mut creds = std::collections::HashMap::new();
|
||||
creds.insert(
|
||||
"TELEGRAM_BOT_TOKEN".to_string(),
|
||||
"8218490433:AAEZeUxwqZ5OO3mOCXv7fKvpdhDgsmBBNis".to_string(),
|
||||
TEST_TELEGRAM_BOT_TOKEN.to_string(),
|
||||
);
|
||||
creds.insert("OTHER_SECRET".to_string(), "s3cret".to_string());
|
||||
|
||||
@@ -4022,13 +4023,15 @@ mod tests {
|
||||
Arc::new(PairingStore::new()),
|
||||
);
|
||||
|
||||
let error = "HTTP request failed: error sending request for url \
|
||||
(https://api.telegram.org/bot8218490433:AAEZeUxwqZ5OO3mOCXv7fKvpdhDgsmBBNis/getUpdates)";
|
||||
let error = format!(
|
||||
"HTTP request failed: error sending request for url \
|
||||
(https://api.telegram.org/bot{TEST_TELEGRAM_BOT_TOKEN}/getUpdates)"
|
||||
);
|
||||
|
||||
let redacted = store.redact_credentials(error);
|
||||
let redacted = store.redact_credentials(&error);
|
||||
|
||||
assert!(
|
||||
!redacted.contains("8218490433:AAEZeUxwqZ5OO3mOCXv7fKvpdhDgsmBBNis"),
|
||||
!redacted.contains(TEST_TELEGRAM_BOT_TOKEN),
|
||||
"credential value should be redacted"
|
||||
);
|
||||
assert!(
|
||||
|
||||
+27
-26
@@ -83,14 +83,15 @@ pub async fn auth_middleware(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::testing::credentials::{TEST_AUTH_SECRET_TOKEN, TEST_BEARER_TOKEN};
|
||||
|
||||
#[test]
|
||||
fn test_auth_state_clone() {
|
||||
let state = AuthState {
|
||||
token: "test-token".to_string(),
|
||||
token: TEST_BEARER_TOKEN.to_string(),
|
||||
};
|
||||
let cloned = state.clone();
|
||||
assert_eq!(cloned.token, "test-token");
|
||||
assert_eq!(cloned.token, TEST_BEARER_TOKEN);
|
||||
}
|
||||
|
||||
use axum::Router;
|
||||
@@ -120,10 +121,10 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_valid_bearer_token_passes() {
|
||||
let app = test_app("secret-token");
|
||||
let app = test_app(TEST_AUTH_SECRET_TOKEN);
|
||||
let req = Request::builder()
|
||||
.uri("/api/chat/events")
|
||||
.header("Authorization", "Bearer secret-token")
|
||||
.header("Authorization", format!("Bearer {TEST_AUTH_SECRET_TOKEN}"))
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
let resp = app.oneshot(req).await.unwrap();
|
||||
@@ -132,7 +133,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_invalid_bearer_token_rejected() {
|
||||
let app = test_app("secret-token");
|
||||
let app = test_app(TEST_AUTH_SECRET_TOKEN);
|
||||
let req = Request::builder()
|
||||
.uri("/api/chat/events")
|
||||
.header("Authorization", "Bearer wrong-token")
|
||||
@@ -144,9 +145,9 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_query_token_allowed_for_chat_events() {
|
||||
let app = test_app("secret-token");
|
||||
let app = test_app(TEST_AUTH_SECRET_TOKEN);
|
||||
let req = Request::builder()
|
||||
.uri("/api/chat/events?token=secret-token")
|
||||
.uri(format!("/api/chat/events?token={TEST_AUTH_SECRET_TOKEN}"))
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
let resp = app.oneshot(req).await.unwrap();
|
||||
@@ -155,9 +156,9 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_query_token_allowed_for_logs_events() {
|
||||
let app = test_app("secret-token");
|
||||
let app = test_app(TEST_AUTH_SECRET_TOKEN);
|
||||
let req = Request::builder()
|
||||
.uri("/api/logs/events?token=secret-token")
|
||||
.uri(format!("/api/logs/events?token={TEST_AUTH_SECRET_TOKEN}"))
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
let resp = app.oneshot(req).await.unwrap();
|
||||
@@ -166,9 +167,9 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_query_token_allowed_for_ws_upgrade() {
|
||||
let app = test_app("secret-token");
|
||||
let app = test_app(TEST_AUTH_SECRET_TOKEN);
|
||||
let req = Request::builder()
|
||||
.uri("/api/chat/ws?token=secret-token")
|
||||
.uri(format!("/api/chat/ws?token={TEST_AUTH_SECRET_TOKEN}"))
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
let resp = app.oneshot(req).await.unwrap();
|
||||
@@ -202,9 +203,9 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_query_token_rejected_for_non_sse_get() {
|
||||
let app = test_app("secret-token");
|
||||
let app = test_app(TEST_AUTH_SECRET_TOKEN);
|
||||
let req = Request::builder()
|
||||
.uri("/api/chat/history?token=secret-token")
|
||||
.uri(format!("/api/chat/history?token={TEST_AUTH_SECRET_TOKEN}"))
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
let resp = app.oneshot(req).await.unwrap();
|
||||
@@ -213,10 +214,10 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_query_token_rejected_for_post() {
|
||||
let app = test_app("secret-token");
|
||||
let app = test_app(TEST_AUTH_SECRET_TOKEN);
|
||||
let req = Request::builder()
|
||||
.method(Method::POST)
|
||||
.uri("/api/chat/send?token=secret-token")
|
||||
.uri(format!("/api/chat/send?token={TEST_AUTH_SECRET_TOKEN}"))
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
let resp = app.oneshot(req).await.unwrap();
|
||||
@@ -225,7 +226,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_query_token_invalid_rejected() {
|
||||
let app = test_app("secret-token");
|
||||
let app = test_app(TEST_AUTH_SECRET_TOKEN);
|
||||
let req = Request::builder()
|
||||
.uri("/api/chat/events?token=wrong-token")
|
||||
.body(Body::empty())
|
||||
@@ -236,7 +237,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_no_auth_at_all_rejected() {
|
||||
let app = test_app("secret-token");
|
||||
let app = test_app(TEST_AUTH_SECRET_TOKEN);
|
||||
let req = Request::builder()
|
||||
.uri("/api/chat/events")
|
||||
.body(Body::empty())
|
||||
@@ -247,11 +248,11 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_bearer_header_works_for_post() {
|
||||
let app = test_app("secret-token");
|
||||
let app = test_app(TEST_AUTH_SECRET_TOKEN);
|
||||
let req = Request::builder()
|
||||
.method(Method::POST)
|
||||
.uri("/api/chat/send")
|
||||
.header("Authorization", "Bearer secret-token")
|
||||
.header("Authorization", format!("Bearer {TEST_AUTH_SECRET_TOKEN}"))
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
let resp = app.oneshot(req).await.unwrap();
|
||||
@@ -260,10 +261,10 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_bearer_prefix_case_insensitive() {
|
||||
let app = test_app("secret-token");
|
||||
let app = test_app(TEST_AUTH_SECRET_TOKEN);
|
||||
let req = Request::builder()
|
||||
.uri("/api/chat/events")
|
||||
.header("Authorization", "bearer secret-token")
|
||||
.header("Authorization", format!("bearer {TEST_AUTH_SECRET_TOKEN}"))
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
let resp = app.oneshot(req).await.unwrap();
|
||||
@@ -272,10 +273,10 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_bearer_prefix_mixed_case() {
|
||||
let app = test_app("secret-token");
|
||||
let app = test_app(TEST_AUTH_SECRET_TOKEN);
|
||||
let req = Request::builder()
|
||||
.uri("/api/chat/events")
|
||||
.header("Authorization", "BEARER secret-token")
|
||||
.header("Authorization", format!("BEARER {TEST_AUTH_SECRET_TOKEN}"))
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
let resp = app.oneshot(req).await.unwrap();
|
||||
@@ -284,7 +285,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_empty_bearer_token_rejected() {
|
||||
let app = test_app("secret-token");
|
||||
let app = test_app(TEST_AUTH_SECRET_TOKEN);
|
||||
let req = Request::builder()
|
||||
.uri("/api/chat/events")
|
||||
.header("Authorization", "Bearer ")
|
||||
@@ -296,10 +297,10 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_token_with_whitespace_rejected() {
|
||||
let app = test_app("secret-token");
|
||||
let app = test_app(TEST_AUTH_SECRET_TOKEN);
|
||||
let req = Request::builder()
|
||||
.uri("/api/chat/events")
|
||||
.header("Authorization", "Bearer secret-token")
|
||||
.header("Authorization", format!("Bearer {TEST_AUTH_SECRET_TOKEN}"))
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
let resp = app.oneshot(req).await.unwrap();
|
||||
|
||||
@@ -2379,6 +2379,7 @@ struct GatewayStatusResponse {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::testing::credentials::TEST_GATEWAY_CRYPTO_KEY;
|
||||
|
||||
#[test]
|
||||
fn test_build_turns_from_db_messages_complete() {
|
||||
@@ -2552,7 +2553,7 @@ mod tests {
|
||||
// Build an ExtensionManager so the handler can look up flows
|
||||
let secrets = Arc::new(crate::secrets::InMemorySecretsStore::new(Arc::new(
|
||||
crate::secrets::SecretsCrypto::new(secrecy::SecretString::from(
|
||||
"test-key-at-least-32-chars-long!!".to_string(),
|
||||
TEST_GATEWAY_CRYPTO_KEY.to_string(),
|
||||
))
|
||||
.expect("crypto"),
|
||||
)));
|
||||
@@ -2602,7 +2603,7 @@ mod tests {
|
||||
let secrets: Arc<dyn crate::secrets::SecretsStore + Send + Sync> =
|
||||
Arc::new(crate::secrets::InMemorySecretsStore::new(Arc::new(
|
||||
crate::secrets::SecretsCrypto::new(secrecy::SecretString::from(
|
||||
"test-key-at-least-32-chars-long!!".to_string(),
|
||||
TEST_GATEWAY_CRYPTO_KEY.to_string(),
|
||||
))
|
||||
.expect("crypto"),
|
||||
)));
|
||||
@@ -2708,7 +2709,7 @@ mod tests {
|
||||
let secrets: Arc<dyn crate::secrets::SecretsStore + Send + Sync> =
|
||||
Arc::new(crate::secrets::InMemorySecretsStore::new(Arc::new(
|
||||
crate::secrets::SecretsCrypto::new(secrecy::SecretString::from(
|
||||
"test-key-at-least-32-chars-long!!".to_string(),
|
||||
TEST_GATEWAY_CRYPTO_KEY.to_string(),
|
||||
))
|
||||
.expect("crypto"),
|
||||
)));
|
||||
|
||||
Reference in New Issue
Block a user