Skip to main content

polyoxide_clob/account/
credentials.rs

1use std::fmt;
2
3use serde::{Deserialize, Serialize};
4
5/// API credentials for L2 authentication
6#[derive(Clone, Serialize, Deserialize)]
7pub struct Credentials {
8    pub key: String,
9    pub secret: String,
10    pub passphrase: String,
11}
12
13impl fmt::Debug for Credentials {
14    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15        f.debug_struct("Credentials")
16            .field("key", &"<redacted>")
17            .field("secret", &"<redacted>")
18            .field("passphrase", &"<redacted>")
19            .finish()
20    }
21}
22
23#[cfg(test)]
24mod tests {
25    use super::*;
26
27    #[test]
28    fn debug_redacts_all_fields() {
29        let creds = Credentials {
30            key: "my-api-key-12345".to_string(),
31            secret: "my-super-secret".to_string(),
32            passphrase: "my-passphrase-xyz".to_string(),
33        };
34        let debug = format!("{:?}", creds);
35
36        assert!(
37            !debug.contains("my-api-key-12345"),
38            "Debug must not leak key: {}",
39            debug
40        );
41        assert!(
42            !debug.contains("my-super-secret"),
43            "Debug must not leak secret: {}",
44            debug
45        );
46        assert!(
47            !debug.contains("my-passphrase-xyz"),
48            "Debug must not leak passphrase: {}",
49            debug
50        );
51        assert!(
52            debug.contains("<redacted>"),
53            "Debug should show <redacted>: {}",
54            debug
55        );
56    }
57
58    #[test]
59    fn credentials_serde_roundtrip() {
60        let original = Credentials {
61            key: "k".to_string(),
62            secret: "s".to_string(),
63            passphrase: "p".to_string(),
64        };
65        let json = serde_json::to_string(&original).unwrap();
66        let deserialized: Credentials = serde_json::from_str(&json).unwrap();
67        assert_eq!(deserialized.key, "k");
68        assert_eq!(deserialized.secret, "s");
69        assert_eq!(deserialized.passphrase, "p");
70    }
71
72    #[test]
73    fn credentials_clone() {
74        let original = Credentials {
75            key: "k".to_string(),
76            secret: "s".to_string(),
77            passphrase: "p".to_string(),
78        };
79        let cloned = original.clone();
80        assert_eq!(cloned.key, original.key);
81        assert_eq!(cloned.secret, original.secret);
82        assert_eq!(cloned.passphrase, original.passphrase);
83    }
84}