Rust
84 lines · 2,765 bytes
use reqwest::blocking::Client;
use serde_json::{json, Value};
use std::collections::HashMap;
pub struct LibreAuth {
pub name: String,
pub owner_id: String,
pub version: String,
pub url: String,
pub session_id: Option<String>,
pub enckey: Option<String>,
}
impl LibreAuth {
pub fn new(name: &str, owner_id: &str, version: &str, url: &str) -> Self {
Self {
name: name.to_string(),
owner_id: owner_id.to_string(),
version: version.to_string(),
url: format!("{}/", url.trim_end_matches('/')),
session_id: None,
enckey: None,
}
}
pub fn init(&mut self) -> Result<Value, String> {
let enc: String = (0..35).map(|_| format!("{:x}", rand::random::<u8>() % 16)).collect();
self.enckey = Some(enc.clone());
let res = self.req(&[
("type", "init"),
("ver", &self.version),
("enckey", &enc),
])?;
if !res["success"].as_bool().unwrap_or(false) {
return Err(res["message"].as_str().unwrap_or("init failed").to_string());
}
self.session_id = Some(res["sessionid"].as_str().unwrap_or("").to_string());
Ok(res)
}
pub fn login(&self, user: &str, pass: &str, hwid: &str) -> Result<Value, String> {
self.auth(&[
("type", "login"),
("username", user),
("pass", pass),
("hwid", hwid),
])
}
pub fn license(&self, key: &str, hwid: &str) -> Result<Value, String> {
self.auth(&[("type", "license"), ("key", key), ("hwid", hwid)])
}
pub fn token(&self, token: &str, hwid: &str) -> Result<Value, String> {
self.auth(&[("type", "token"), ("token", token), ("hwid", hwid)])
}
fn auth(&self, extra: &[(&str, &str)]) -> Result<Value, String> {
let res = self.req(extra)?;
if !res["success"].as_bool().unwrap_or(false) {
return Err(res["message"].as_str().unwrap_or("auth failed").to_string());
}
Ok(res["info"].clone())
}
fn req(&self, extra: &[(&str, &str)]) -> Result<Value, String> {
let client = Client::new();
let mut form: HashMap<&str, &str> = HashMap::new();
form.insert("name", &self.name);
form.insert("ownerid", &self.owner_id);
if let Some(ref sid) = self.session_id {
form.insert("sessionid", sid);
}
for (k, v) in extra {
form.insert(k, v);
}
let resp = client.post(&self.url).form(&form).send().map_err(|e| e.to_string())?;
if resp.status().as_u16() == 429 {
return Err("Rate limited".into());
}
resp.json().map_err(|e| e.to_string())
}
}