qcells/
client.rs

1use crate::models::{LoginResponse};
2use crate::user::User;
3use super::models::Login;
4
5pub const BASE_URL: &str = "https://www.portal-q-cells.us/phoebus";
6
7pub struct Client {
8    pub user: User,
9}
10
11impl Client {
12    /// Creates a new API-Client with a logged in user
13    ///
14    /// # Arguments
15    ///
16    /// * `username`: Username of the user
17    /// * `password`: Plain-text password of the user
18    ///
19    /// returns: Result<Client, Error>
20    ///
21    /// # Examples
22    ///
23    /// ```
24    /// // Default-Guest user
25    /// let client = qcells::Client::new("guest", "solax123456").expect("login failed");
26    /// println!("{}", client.user.username);
27    /// ```
28    pub fn new(username: &str, password: &str) -> Result<Client> {
29        let login_response = match login(username, password) {
30            Ok(resp) => {
31                if !resp.success {
32                    return Err(Error { message: "login failed".to_string() });
33                }
34                resp
35            }
36            Err(err) => return Err(err),
37        };
38        return Ok(Client { user: User::from_login(&login_response) });
39    }
40}
41
42pub(crate) fn login(username: &str, password: &str) -> Result<LoginResponse> {
43    let hash = format!("{:x}", md5::compute(password.as_bytes()));
44    let login = Login { username: username.to_string(), password: hash };
45
46    let client = reqwest::blocking::Client::new();
47    let request = client.post(format!("{}/login/loginNew", BASE_URL))
48        .header("Accept", "application/json")
49        .header("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8")
50        .form(&login).build();
51
52    let request = match request {
53        Ok(req) => req,
54        Err(err) => return Err(Error { message: err.to_string() })
55    };
56    let response = match client.execute(request) {
57        Ok(resp) => resp,
58        Err(err) => return Err(Error { message: err.to_string() })
59    };
60    if !response.status().is_success() {
61        return Err(Error { message: format!("Received invalid status code {}", response.status().as_u16()) });
62    }
63
64    let login_response: reqwest::Result<LoginResponse> = response.json();
65    let login_response = match login_response {
66        Ok(resp) => resp,
67        Err(err) => return Err(Error { message: err.to_string() })
68    };
69    return Ok(login_response);
70}
71
72/// A `Result` alias where the `Err` case is `qcells::Error`.
73pub type Result<T> = std::result::Result<T, Error>;
74
75/// The Errors that may occur when processing a `Request`.
76#[derive(Debug)]
77pub struct Error {
78    pub message: String,
79}
80
81#[cfg(test)]
82mod tests {
83    use super::*;
84
85    #[test]
86    fn test_login() {
87        let client = Client::new(
88            "guest",
89            "solax123456",
90        );
91        let client = match client {
92            Ok(client) => client,
93            Err(err) => panic!("{}", err.message)
94        };
95        let user = client.user;
96        println!("Token is: {}", user.token);
97        assert_ne!(user.token, "")
98    }
99}