wlancfg_lib/config_management/
stash_conversion.rs

1// Copyright 2020 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use super::network_config::{Credential, NetworkConfig, NetworkIdentifier, SecurityType};
6use crate::client::types as client_types;
7use std::collections::HashMap;
8use wlan_storage::policy as storage;
9
10impl From<storage::NetworkIdentifier> for NetworkIdentifier {
11    fn from(item: storage::NetworkIdentifier) -> Self {
12        Self {
13            ssid: client_types::Ssid::from_bytes_unchecked(item.ssid),
14            security_type: item.security_type.into(),
15        }
16    }
17}
18
19impl From<NetworkIdentifier> for storage::NetworkIdentifier {
20    fn from(item: NetworkIdentifier) -> Self {
21        Self { ssid: item.ssid.into(), security_type: item.security_type.into() }
22    }
23}
24
25impl From<storage::SecurityType> for SecurityType {
26    fn from(item: storage::SecurityType) -> Self {
27        match item {
28            storage::SecurityType::None => SecurityType::None,
29            storage::SecurityType::Wep => SecurityType::Wep,
30            storage::SecurityType::Wpa => SecurityType::Wpa,
31            storage::SecurityType::Wpa2 => SecurityType::Wpa2,
32            storage::SecurityType::Wpa3 => SecurityType::Wpa3,
33        }
34    }
35}
36
37impl From<SecurityType> for storage::SecurityType {
38    fn from(item: SecurityType) -> Self {
39        match item {
40            SecurityType::None => storage::SecurityType::None,
41            SecurityType::Wep => storage::SecurityType::Wep,
42            SecurityType::Wpa => storage::SecurityType::Wpa,
43            SecurityType::Wpa2 => storage::SecurityType::Wpa2,
44            SecurityType::Wpa3 => storage::SecurityType::Wpa3,
45        }
46    }
47}
48
49impl From<storage::Credential> for Credential {
50    fn from(item: storage::Credential) -> Self {
51        match item {
52            storage::Credential::None => Credential::None,
53            storage::Credential::Password(pass) => Credential::Password(pass),
54            storage::Credential::Psk(psk) => Credential::Psk(psk),
55        }
56    }
57}
58
59impl From<Credential> for storage::Credential {
60    fn from(item: Credential) -> Self {
61        match item {
62            Credential::None => storage::Credential::None,
63            Credential::Password(pass) => storage::Credential::Password(pass),
64            Credential::Psk(psk) => storage::Credential::Psk(psk),
65        }
66    }
67}
68
69impl From<NetworkConfig> for storage::PersistentStorageData {
70    fn from(item: NetworkConfig) -> Self {
71        Self {
72            ssid: item.ssid.to_vec(),
73            security_type: item.security_type.into(),
74            credential: item.credential.into(),
75            has_ever_connected: item.has_ever_connected,
76        }
77    }
78}
79
80/// Convert configs to the persistent data for configs. It takes in a map of NetworkConfigs
81/// corresponding to the way network configs are internally tracked.
82pub fn persistent_data_from_config_map(
83    network_config: &HashMap<NetworkIdentifier, Vec<NetworkConfig>>,
84) -> Vec<storage::PersistentStorageData> {
85    network_config.values().flatten().map(|c| c.clone().into()).collect()
86}
87
88#[cfg(test)]
89mod tests {
90    use super::super::*;
91    use super::*;
92    use test_case::test_case;
93    use wlan_storage::policy as storage;
94
95    #[fuchsia::test]
96    fn network_identifier_to_stash_from_policy() {
97        assert_eq!(
98            storage::NetworkIdentifier::from(NetworkIdentifier {
99                ssid: client_types::Ssid::try_from("ssid").unwrap(),
100                security_type: SecurityType::Wep,
101            }),
102            storage::NetworkIdentifier {
103                ssid: client_types::Ssid::try_from("ssid").unwrap().into(),
104                security_type: storage::SecurityType::Wep,
105            }
106        );
107    }
108
109    #[fuchsia::test]
110    fn network_identifier_to_policy_from_stash() {
111        assert_eq!(
112            NetworkIdentifier::from(storage::NetworkIdentifier {
113                ssid: client_types::Ssid::try_from("ssid").unwrap().into(),
114                security_type: storage::SecurityType::Wep,
115            }),
116            NetworkIdentifier {
117                ssid: client_types::Ssid::try_from("ssid").unwrap(),
118                security_type: SecurityType::Wep
119            }
120        );
121    }
122
123    #[fuchsia::test]
124    fn security_type_to_stash_from_policy() {
125        assert_eq!(storage::SecurityType::from(SecurityType::None), storage::SecurityType::None);
126        assert_eq!(storage::SecurityType::from(SecurityType::Wep), storage::SecurityType::Wep);
127        assert_eq!(storage::SecurityType::from(SecurityType::Wpa), storage::SecurityType::Wpa);
128        assert_eq!(storage::SecurityType::from(SecurityType::Wpa2), storage::SecurityType::Wpa2);
129        assert_eq!(storage::SecurityType::from(SecurityType::Wpa3), storage::SecurityType::Wpa3);
130    }
131
132    #[fuchsia::test]
133    fn security_type_to_policy_from_stash() {
134        assert_eq!(SecurityType::from(storage::SecurityType::None), SecurityType::None);
135        assert_eq!(SecurityType::from(storage::SecurityType::Wep), SecurityType::Wep);
136        assert_eq!(SecurityType::from(storage::SecurityType::Wpa), SecurityType::Wpa);
137        assert_eq!(SecurityType::from(storage::SecurityType::Wpa2), SecurityType::Wpa2);
138        assert_eq!(SecurityType::from(storage::SecurityType::Wpa3), SecurityType::Wpa3);
139    }
140
141    #[fuchsia::test]
142    fn credential_to_stash_from_policy() {
143        assert_eq!(storage::Credential::from(Credential::None), storage::Credential::None);
144        assert_eq!(
145            storage::Credential::from(Credential::Password(b"foo_pass123".to_vec())),
146            storage::Credential::Password(b"foo_pass123".to_vec())
147        );
148        assert_eq!(
149            storage::Credential::from(Credential::Psk(b"foo_psk123".to_vec())),
150            storage::Credential::Psk(b"foo_psk123".to_vec())
151        );
152    }
153
154    #[fuchsia::test]
155    fn credential_to_policy_from_stash() {
156        assert_eq!(Credential::from(storage::Credential::None), Credential::None);
157        assert_eq!(
158            Credential::from(storage::Credential::Password(b"foo_pass123".to_vec())),
159            Credential::Password(b"foo_pass123".to_vec())
160        );
161        assert_eq!(
162            Credential::from(storage::Credential::Password(b"foo_psk123".to_vec())),
163            Credential::Password(b"foo_psk123".to_vec())
164        );
165    }
166
167    #[test_case(true)]
168    #[test_case(false)]
169    #[fuchsia::test(add_test_attr = false)]
170    fn persistent_data_from_network_config_has_connected(has_ever_connected: bool) {
171        // Check that from() works when has_ever_connected is true and false.
172        let ssid = "ssid";
173        let security_type = SecurityType::Wpa3;
174        let stash_security = storage::SecurityType::Wpa3;
175        let id = NetworkIdentifier::try_from(ssid, security_type).unwrap();
176        let credential = Credential::Password(b"foo_pass".to_vec());
177        let network_config = NetworkConfig::new(id, credential, has_ever_connected)
178            .expect("failed to create network config");
179        assert_eq!(
180            storage::PersistentStorageData::from(network_config),
181            storage::PersistentStorageData {
182                ssid: ssid.as_bytes().to_vec(),
183                security_type: stash_security,
184                credential: storage::Credential::Password(b"foo_pass".to_vec()),
185                has_ever_connected
186            }
187        );
188    }
189
190    #[test_case(SecurityType::Wpa, storage::SecurityType::Wpa)]
191    #[fuchsia::test(add_test_attr = false)]
192    fn persistent_data_from_network_config_security(
193        security: SecurityType,
194        storage_security: storage::SecurityType,
195    ) {
196        // Check that from() works for different security types
197        let ssid = "ssid";
198        let id = NetworkIdentifier::try_from(ssid, security).unwrap();
199        let has_ever_connected = true;
200
201        // Use a password for WPA, PSK for WEP, or None for open networks.
202        let (credential, storage_credential) = match security {
203            SecurityType::None => (Credential::None, storage::Credential::None),
204            SecurityType::Wep => {
205                let psk_bytes = vec![1; network_config::WPA_PSK_BYTE_LEN];
206                (Credential::Psk(psk_bytes.clone()), storage::Credential::Psk(psk_bytes))
207            }
208            SecurityType::Wpa | SecurityType::Wpa2 | SecurityType::Wpa3 => (
209                Credential::Password(b"foo_pass".to_vec()),
210                storage::Credential::Password(b"foo_pass".to_vec()),
211            ),
212        };
213
214        let network_config = NetworkConfig::new(id, credential, has_ever_connected)
215            .expect("failed to create network config");
216        assert_eq!(
217            storage::PersistentStorageData::from(network_config),
218            storage::PersistentStorageData {
219                ssid: ssid.as_bytes().to_vec(),
220                security_type: storage_security,
221                credential: storage_credential,
222                has_ever_connected
223            }
224        );
225    }
226}