huawei_dongle_api/models/
auth.rs1use super::enums::{LockStatus, LoginStatus};
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct LoginState {
9 #[serde(rename = "password_type")]
11 pub password_type: String,
12
13 #[serde(rename = "extern_password_type")]
15 pub extern_password_type: String,
16
17 #[serde(rename = "history_login_flag")]
19 pub history_login_flag: String,
20
21 #[serde(rename = "State")]
23 pub state: LoginStatus,
24
25 #[serde(rename = "guidemodifypwdpageflag")]
27 pub guide_modify_pwd_page_flag: String,
28
29 #[serde(rename = "rsapadingtype")]
31 pub rsa_padding_type: String,
32
33 #[serde(rename = "accounts_number")]
35 pub accounts_number: String,
36
37 #[serde(rename = "wifipwdsamewithwebpwd")]
39 pub wifi_pwd_same_with_web_pwd: String,
40
41 #[serde(rename = "remainwaittime")]
43 pub remain_wait_time: String,
44
45 #[serde(rename = "lockstatus")]
47 pub lock_status: LockStatus,
48
49 #[serde(rename = "forceskipguide")]
51 pub force_skip_guide: String,
52
53 #[serde(rename = "username")]
55 pub username: String,
56
57 #[serde(rename = "firstlogin")]
59 pub first_login: String,
60
61 #[serde(rename = "userlevel")]
63 pub user_level: String,
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize)]
68pub struct LoginRequest {
69 #[serde(rename = "Username")]
71 pub username: String,
72
73 #[serde(rename = "Password")]
75 pub password: String,
76
77 #[serde(rename = "password_type")]
79 pub password_type: String,
80}
81
82#[derive(Debug, Clone, Serialize, Deserialize)]
84pub struct LogoutRequest {
85 #[serde(rename = "Logout")]
87 pub logout: String,
88}
89
90impl LoginState {
91 pub fn is_logged_in(&self) -> bool {
93 self.state.is_logged_in()
94 }
95
96 pub fn is_locked(&self) -> bool {
98 self.lock_status.is_locked()
99 }
100
101 pub fn password_encoding(&self) -> PasswordEncoding {
103 match self.password_type.as_str() {
104 "0" => PasswordEncoding::Base64,
105 "3" => PasswordEncoding::Base64AfterChange,
106 "4" => PasswordEncoding::Sha256,
107 _ => PasswordEncoding::Unknown,
108 }
109 }
110}
111
112#[derive(Debug, Clone, PartialEq)]
114pub enum PasswordEncoding {
115 Base64,
117 Base64AfterChange,
119 Sha256,
121 Unknown,
123}
124
125impl LoginRequest {
126 pub fn new(username: String, password: String, password_type: String) -> Self {
128 Self {
129 username,
130 password,
131 password_type,
132 }
133 }
134}
135
136impl LogoutRequest {
137 pub fn new() -> Self {
139 Self {
140 logout: "1".to_string(),
141 }
142 }
143}
144
145impl Default for LogoutRequest {
146 fn default() -> Self {
147 Self::new()
148 }
149}
150
151#[cfg(test)]
152mod tests {
153 use super::*;
154
155 #[test]
156 fn test_login_state_parsing() {
157 let xml = r#"
158 <response>
159 <password_type>4</password_type>
160 <extern_password_type>1</extern_password_type>
161 <history_login_flag>0</history_login_flag>
162 <State>-1</State>
163 <guidemodifypwdpageflag>0</guidemodifypwdpageflag>
164 <rsapadingtype>1</rsapadingtype>
165 <accounts_number>1</accounts_number>
166 <wifipwdsamewithwebpwd>0</wifipwdsamewithwebpwd>
167 <remainwaittime>0</remainwaittime>
168 <lockstatus>0</lockstatus>
169 <forceskipguide>0</forceskipguide>
170 <username></username>
171 <firstlogin>0</firstlogin>
172 <userlevel></userlevel>
173 </response>"#;
174
175 let state: LoginState = serde_xml_rs::from_str(xml).unwrap();
176 assert_eq!(state.password_type, "4");
177 assert_eq!(state.state, LoginStatus::NotLoggedIn);
178 assert!(!state.is_logged_in());
179 assert!(!state.is_locked());
180 assert_eq!(state.password_encoding(), PasswordEncoding::Sha256);
181 }
182
183 #[test]
184 fn test_login_request_serialization() {
185 let request = LoginRequest::new(
186 "admin".to_string(),
187 "encoded_password".to_string(),
188 "4".to_string(),
189 );
190
191 let xml = serde_xml_rs::to_string(&request).unwrap();
192 assert!(xml.contains("<Username>admin</Username>"));
193 assert!(xml.contains("<Password>encoded_password</Password>"));
194 assert!(xml.contains("<password_type>4</password_type>"));
195 }
196
197 #[test]
198 fn test_password_encoding_detection() {
199 let mut state = LoginState {
200 password_type: "0".to_string(),
201 state: LoginStatus::NotLoggedIn,
202 lock_status: LockStatus::Unlocked,
203 extern_password_type: "1".to_string(),
204 history_login_flag: "0".to_string(),
205 guide_modify_pwd_page_flag: "0".to_string(),
206 rsa_padding_type: "1".to_string(),
207 accounts_number: "1".to_string(),
208 wifi_pwd_same_with_web_pwd: "0".to_string(),
209 remain_wait_time: "0".to_string(),
210 force_skip_guide: "0".to_string(),
211 username: "".to_string(),
212 first_login: "0".to_string(),
213 user_level: "".to_string(),
214 };
215
216 assert_eq!(state.password_encoding(), PasswordEncoding::Base64);
217
218 state.password_type = "4".to_string();
219 assert_eq!(state.password_encoding(), PasswordEncoding::Sha256);
220 }
221}