bitwarden_exporters/cxf/
api_key.rs

1use credential_exchange_format::ApiKeyCredential;
2
3use crate::{cxf::editable_field::create_field, Field};
4
5/// Convert API key credentials to custom fields
6pub(super) fn api_key_to_fields(api_key: &ApiKeyCredential) -> Vec<Field> {
7    [
8        api_key
9            .key
10            .as_ref()
11            .map(|key| create_field(key, Some("API Key"))),
12        api_key
13            .username
14            .as_ref()
15            .map(|username| create_field(username, Some("Username"))),
16        api_key
17            .key_type
18            .as_ref()
19            .map(|key_type| create_field(key_type, Some("Key Type"))),
20        api_key
21            .url
22            .as_ref()
23            .map(|url| create_field(url, Some("URL"))),
24        api_key
25            .valid_from
26            .as_ref()
27            .map(|valid_from| create_field(valid_from, Some("Valid From"))),
28        api_key
29            .expiry_date
30            .as_ref()
31            .map(|expiry_date| create_field(expiry_date, Some("Expiry Date"))),
32    ]
33    .into_iter()
34    .flatten()
35    .collect()
36}
37
38#[cfg(test)]
39mod tests {
40    use bitwarden_vault::FieldType;
41    use chrono::NaiveDate;
42    use credential_exchange_format::{EditableFieldConcealedString, EditableFieldDate};
43
44    use super::*;
45
46    #[test]
47    fn test_api_key_to_fields_all_fields() {
48        let api_key = ApiKeyCredential {
49            key: Some(
50                EditableFieldConcealedString("AIzaSyAyRofL-VJHZofHc-qOSkqVOdhvgQoJADk".to_string())
51                    .into(),
52            ),
53            username: Some("john_doe".to_string().into()),
54            key_type: Some("Bearer".to_string().into()),
55            url: Some("https://api.example.com".to_string().into()),
56            valid_from: Some(
57                EditableFieldDate(NaiveDate::from_ymd_opt(2025, 1, 1).unwrap()).into(),
58            ),
59            expiry_date: Some(
60                EditableFieldDate(NaiveDate::from_ymd_opt(2026, 1, 1).unwrap()).into(),
61            ),
62        };
63
64        let fields = api_key_to_fields(&api_key);
65
66        let expected_fields = vec![
67            Field {
68                name: Some("API Key".to_string()),
69                value: Some("AIzaSyAyRofL-VJHZofHc-qOSkqVOdhvgQoJADk".to_string()),
70                r#type: FieldType::Hidden as u8,
71                linked_id: None,
72            },
73            Field {
74                name: Some("Username".to_string()),
75                value: Some("john_doe".to_string()),
76                r#type: FieldType::Text as u8,
77                linked_id: None,
78            },
79            Field {
80                name: Some("Key Type".to_string()),
81                value: Some("Bearer".to_string()),
82                r#type: FieldType::Text as u8,
83                linked_id: None,
84            },
85            Field {
86                name: Some("URL".to_string()),
87                value: Some("https://api.example.com".to_string()),
88                r#type: FieldType::Text as u8,
89                linked_id: None,
90            },
91            Field {
92                name: Some("Valid From".to_string()),
93                value: Some("2025-01-01".to_string()),
94                r#type: FieldType::Text as u8,
95                linked_id: None,
96            },
97            Field {
98                name: Some("Expiry Date".to_string()),
99                value: Some("2026-01-01".to_string()),
100                r#type: FieldType::Text as u8,
101                linked_id: None,
102            },
103        ];
104
105        assert_eq!(fields, expected_fields);
106    }
107
108    #[test]
109    fn test_api_key_to_fields_minimal() {
110        let api_key = ApiKeyCredential {
111            key: Some("test-api-key".to_string().into()),
112            username: None,
113            key_type: None,
114            url: None,
115            valid_from: None,
116            expiry_date: None,
117        };
118
119        let fields = api_key_to_fields(&api_key);
120
121        let expected_fields = vec![Field {
122            name: Some("API Key".to_string()),
123            value: Some("test-api-key".to_string()),
124            r#type: FieldType::Hidden as u8,
125            linked_id: None,
126        }];
127
128        assert_eq!(fields, expected_fields);
129    }
130
131    #[test]
132    fn test_api_key_to_fields_empty() {
133        let api_key = ApiKeyCredential {
134            key: None,
135            username: None,
136            key_type: None,
137            url: None,
138            valid_from: None,
139            expiry_date: None,
140        };
141
142        let fields = api_key_to_fields(&api_key);
143
144        assert_eq!(fields, vec![]);
145    }
146
147    #[test]
148    fn test_api_key_to_fields_partial() {
149        let api_key = ApiKeyCredential {
150            key: Some("secret-key".to_string().into()),
151            username: Some("test_user".to_string().into()),
152            key_type: Some("API_KEY".to_string().into()),
153            url: None,
154            valid_from: None,
155            expiry_date: None,
156        };
157
158        let fields = api_key_to_fields(&api_key);
159
160        let expected_fields = vec![
161            Field {
162                name: Some("API Key".to_string()),
163                value: Some("secret-key".to_string()),
164                r#type: FieldType::Hidden as u8,
165                linked_id: None,
166            },
167            Field {
168                name: Some("Username".to_string()),
169                value: Some("test_user".to_string()),
170                r#type: FieldType::Text as u8,
171                linked_id: None,
172            },
173            Field {
174                name: Some("Key Type".to_string()),
175                value: Some("API_KEY".to_string()),
176                r#type: FieldType::Text as u8,
177                linked_id: None,
178            },
179        ];
180
181        assert_eq!(fields, expected_fields);
182    }
183}