bitwarden_exporters/cxf/
wifi.rs

1use credential_exchange_format::WifiCredential;
2
3use crate::{cxf::editable_field::create_field, Field};
4
5/// Convert WiFi credentials to custom fields following the CXF mapping convention
6pub(super) fn wifi_to_fields(wifi: &WifiCredential) -> Vec<Field> {
7    [
8        // SSID: Text field
9        wifi.ssid.as_ref().map(|ssid| create_field("SSID", ssid)),
10        // Passphrase: Hidden field (concealed-string)
11        wifi.passphrase
12            .as_ref()
13            .map(|passphrase| create_field("Passphrase", passphrase)),
14        // Network Security Type: Text field
15        wifi.network_security_type
16            .as_ref()
17            .map(|security| create_field("Network Security Type", security)),
18        // Hidden: Boolean field
19        wifi.hidden
20            .as_ref()
21            .map(|hidden| create_field("Hidden", hidden)),
22    ]
23    .into_iter()
24    .flatten()
25    .collect()
26}
27
28#[cfg(test)]
29mod tests {
30    use bitwarden_vault::FieldType;
31    use credential_exchange_format::EditableFieldWifiNetworkSecurityType;
32
33    use super::*;
34
35    #[test]
36    fn test_wifi_to_fields_all_fields() {
37        let wifi = WifiCredential {
38            ssid: Some("MyWiFi".to_owned().into()),
39            passphrase: Some("secret123".to_owned().into()),
40            network_security_type: Some(EditableFieldWifiNetworkSecurityType::Wpa2Personal.into()),
41            hidden: Some(false.into()),
42        };
43
44        let fields = wifi_to_fields(&wifi);
45
46        assert_eq!(
47            fields,
48            vec![
49                Field {
50                    name: Some("SSID".to_string()),
51                    value: Some("MyWiFi".to_string()),
52                    r#type: FieldType::Text as u8,
53                    linked_id: None,
54                },
55                Field {
56                    name: Some("Passphrase".to_string()),
57                    value: Some("secret123".to_string()),
58                    r#type: FieldType::Hidden as u8,
59                    linked_id: None,
60                },
61                Field {
62                    name: Some("Network Security Type".to_string()),
63                    value: Some("WPA2 Personal".to_string()),
64                    r#type: FieldType::Text as u8,
65                    linked_id: None,
66                },
67                Field {
68                    name: Some("Hidden".to_string()),
69                    value: Some("false".to_string()),
70                    r#type: FieldType::Boolean as u8,
71                    linked_id: None,
72                },
73            ]
74        );
75    }
76
77    #[test]
78    fn test_wifi_to_fields_minimal() {
79        let wifi = WifiCredential {
80            ssid: Some("BasicWiFi".to_owned().into()),
81            passphrase: None,
82            network_security_type: None,
83            hidden: None,
84        };
85
86        let fields = wifi_to_fields(&wifi);
87
88        assert_eq!(
89            fields,
90            vec![Field {
91                name: Some("SSID".to_string()),
92                value: Some("BasicWiFi".to_string()),
93                r#type: FieldType::Text as u8,
94                linked_id: None,
95            }]
96        );
97    }
98
99    #[test]
100    fn test_wifi_to_fields_empty() {
101        let wifi = WifiCredential {
102            ssid: None,
103            passphrase: None,
104            network_security_type: None,
105            hidden: None,
106        };
107
108        let fields = wifi_to_fields(&wifi);
109
110        assert_eq!(fields, vec![]);
111    }
112
113    #[test]
114    fn test_wifi_to_fields_wpa3_security() {
115        let wifi = WifiCredential {
116            ssid: Some("SecureWiFi".to_owned().into()),
117            passphrase: Some("password123".to_owned().into()),
118            network_security_type: Some(EditableFieldWifiNetworkSecurityType::Wpa3Personal.into()),
119            hidden: Some(true.into()),
120        };
121
122        let fields = wifi_to_fields(&wifi);
123
124        assert_eq!(
125            fields,
126            vec![
127                Field {
128                    name: Some("SSID".to_string()),
129                    value: Some("SecureWiFi".to_string()),
130                    r#type: FieldType::Text as u8,
131                    linked_id: None,
132                },
133                Field {
134                    name: Some("Passphrase".to_string()),
135                    value: Some("password123".to_string()),
136                    r#type: FieldType::Hidden as u8,
137                    linked_id: None,
138                },
139                Field {
140                    name: Some("Network Security Type".to_string()),
141                    value: Some("WPA3 Personal".to_string()),
142                    r#type: FieldType::Text as u8,
143                    linked_id: None,
144                },
145                Field {
146                    name: Some("Hidden".to_string()),
147                    value: Some("true".to_string()),
148                    r#type: FieldType::Boolean as u8,
149                    linked_id: None,
150                },
151            ]
152        );
153    }
154
155    #[test]
156    fn test_wifi_to_fields_unsecured() {
157        let wifi = WifiCredential {
158            ssid: Some("OpenWiFi".to_owned().into()),
159            passphrase: None,
160            network_security_type: Some(EditableFieldWifiNetworkSecurityType::Unsecured.into()),
161            hidden: None,
162        };
163
164        let fields = wifi_to_fields(&wifi);
165
166        assert_eq!(
167            fields,
168            vec![
169                Field {
170                    name: Some("SSID".to_string()),
171                    value: Some("OpenWiFi".to_string()),
172                    r#type: FieldType::Text as u8,
173                    linked_id: None,
174                },
175                Field {
176                    name: Some("Network Security Type".to_string()),
177                    value: Some("Unsecured".to_string()),
178                    r#type: FieldType::Text as u8,
179                    linked_id: None,
180                },
181            ]
182        );
183    }
184
185    #[test]
186    fn test_wifi_to_fields_wep_security() {
187        let wifi = WifiCredential {
188            ssid: Some("LegacyWiFi".to_owned().into()),
189            passphrase: Some("wepkey123".to_owned().into()),
190            network_security_type: Some(EditableFieldWifiNetworkSecurityType::Wep.into()),
191            hidden: None,
192        };
193
194        let fields = wifi_to_fields(&wifi);
195
196        assert_eq!(
197            fields,
198            vec![
199                Field {
200                    name: Some("SSID".to_string()),
201                    value: Some("LegacyWiFi".to_string()),
202                    r#type: FieldType::Text as u8,
203                    linked_id: None,
204                },
205                Field {
206                    name: Some("Passphrase".to_string()),
207                    value: Some("wepkey123".to_string()),
208                    r#type: FieldType::Hidden as u8,
209                    linked_id: None,
210                },
211                Field {
212                    name: Some("Network Security Type".to_string()),
213                    value: Some("WEP".to_string()),
214                    r#type: FieldType::Text as u8,
215                    linked_id: None,
216                },
217            ]
218        );
219    }
220}