1use reqwest::{Client, Url};
2use serde::{Deserialize, Serialize};
3use std::{error::Error, fmt};
4
5#[derive(Debug, Serialize, Deserialize)]
6struct SignInRequest {
7 username: String,
8 password: String,
9}
10
11struct AuthError {
12 message: String,
13}
14
15impl AuthError {
16 fn new(message: String) -> Self {
17 Self { message }
18 }
19}
20
21impl Error for AuthError {}
22
23impl fmt::Display for AuthError {
25 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
26 write!(f, "Failed to sign in. Got response: {}", self.message) }
28}
29
30impl fmt::Debug for AuthError {
32 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
33 write!(f, "{{ file: {}, line: {} }}", file!(), line!()) }
35}
36
37pub async fn sign_in(
38 client: &Client,
39 addr: &str,
40 username: String,
41 password: String,
42 is_udm: bool,
43) -> Result<(), Box<dyn Error>> {
44 let mut url = Url::parse(format!("{}/api/login", addr).as_str()).unwrap();
45 if is_udm {
46 url = Url::parse(format!("{}/api/auth/login", addr).as_str()).unwrap();
47 }
48 println!("Signing in to {}", url);
49 let data: SignInRequest = SignInRequest { username, password };
50
51 let response = match client.post(url.clone()).json(&data).send().await {
52 Ok(r) => r,
53 Err(e) => return Err(Box::new(e)),
54 };
55
56 if !response.status().is_success() {
57 return Err(Box::new(AuthError::new(response.text().await.unwrap())));
58 }
59
60 Ok(())
61}