Skip to main content

lnu_elytra/method/
login.rs

1use std::time::{SystemTime, UNIX_EPOCH};
2
3use serde::Serialize;
4
5use crate::{
6    Client,
7    error::{Error, R},
8    utils::{EncPwd, PublicKey, ToHtml, UseInputValue},
9};
10
11impl Client {
12    /// 登录
13    pub async fn login(&mut self, username: &str, password: &str) -> R {
14        let doc = self.get(&Client::LOGIN_URL).send().await?.doc().await?;
15        let csrftoken = doc.use_val(&Client::S_CSRFTOKEN)?;
16
17        let mm = self
18            .get(&Client::PUBLIC_KEY_URL)
19            .send()
20            .await?
21            .json::<PublicKey>()
22            .await?
23            .into_rsa_key()?
24            .enc_pwd(password)?;
25
26        #[derive(Serialize, Debug)]
27        struct LoginData<'a> {
28            csrftoken: &'a str,
29            yhm: &'a str,
30            mm: &'a str,
31            language: &'a str,
32        }
33
34        let login_data = LoginData {
35            csrftoken: csrftoken,
36            yhm: username,
37            mm: &mm,
38            language: "zh_CN",
39        };
40
41        let timestamp = SystemTime::now().duration_since(UNIX_EPOCH)?.as_millis();
42
43        let login_res = self
44            .post(&Client::LOGIN_URL)
45            .query(&[("time", timestamp)])
46            .form(&login_data)
47            .send()
48            .await?;
49
50        let doc = login_res.doc().await?;
51
52        let u = doc.use_val(&Client::S_SESSION_USER_KEY)?;
53
54        if u != username {
55            return Err(Error::LoginFailed);
56        }
57
58        Ok(())
59    }
60}