feat: Added login and logout function to client
Signed-off-by: Louis Vallat <louis@louis-vallat.xyz>
This commit is contained in:
parent
85c3e93d80
commit
8576f252ba
10
Cargo.toml
10
Cargo.toml
@ -7,4 +7,14 @@ license = "GPL-3.0"
|
|||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
maintenance = { status = "experimental" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
serde_json = "1.0.81"
|
||||||
|
hyper = { version = "0.14", features = ["full"] }
|
||||||
|
tokio = { version = "1", features = ["full"] }
|
||||||
|
tokio-test = "0.4.2"
|
||||||
|
log = "0.4.17"
|
||||||
|
env_logger = "0.9.0"
|
||||||
|
cookie = "0.16"
|
||||||
|
90
src/client.rs
Normal file
90
src/client.rs
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
|
||||||
|
//! A module to handle the client used to store some important data about the
|
||||||
|
//! router.
|
||||||
|
|
||||||
|
use std::net::Ipv4Addr;
|
||||||
|
use cookie::Cookie;
|
||||||
|
use serde_json::json;
|
||||||
|
use hyper::{Method, Request, body::Body, header::{CONTENT_TYPE, SET_COOKIE, AUTHORIZATION, COOKIE}, client::HttpConnector};
|
||||||
|
use log::{trace, debug};
|
||||||
|
|
||||||
|
/// A structure to hold all the necessary data to connect to the router.
|
||||||
|
pub struct Client {
|
||||||
|
ip: String,
|
||||||
|
username: String,
|
||||||
|
password: String,
|
||||||
|
cookies: Vec<String>,
|
||||||
|
context_id: Option<String>,
|
||||||
|
client: hyper::Client<HttpConnector>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
/// Create a new Client using only the password, and using `192.168.1.1` as
|
||||||
|
/// target IP, and `admin` as the default username.
|
||||||
|
pub fn new(password: &str) -> Client {
|
||||||
|
trace!("Creating a new client.");
|
||||||
|
return Client {
|
||||||
|
ip: Ipv4Addr::new(192, 168, 1, 1).to_string(),
|
||||||
|
username: "admin".to_string(),
|
||||||
|
password: password.to_string(),
|
||||||
|
cookies: Vec::new(),
|
||||||
|
context_id: None,
|
||||||
|
client: hyper::Client::new()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Login to the router.
|
||||||
|
pub async fn login(&mut self) {
|
||||||
|
trace!("Logging in.");
|
||||||
|
let post_data = json!({
|
||||||
|
"service": "sah.Device.Information",
|
||||||
|
"method": "createContext",
|
||||||
|
"parameters": {
|
||||||
|
"applicationName": "so_sdkut",
|
||||||
|
"username": self.username,
|
||||||
|
"password": self.password
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let req = Request::builder()
|
||||||
|
.method(Method::POST)
|
||||||
|
.uri(format!("http://{}/ws", self.ip))
|
||||||
|
.header(CONTENT_TYPE, "application/x-sah-ws-4-call+json")
|
||||||
|
.header(AUTHORIZATION, "X-Sah-Login")
|
||||||
|
.body(Body::from(post_data.to_string()))
|
||||||
|
.expect("Could not build request.");
|
||||||
|
let (parts, body) = self.client.request(req).await
|
||||||
|
.expect("There was an issue contacting the router.").into_parts();
|
||||||
|
|
||||||
|
debug!("Status is {}.", parts.status.as_str());
|
||||||
|
debug!("Body was: '{}'.", std::str::from_utf8(
|
||||||
|
&hyper::body::to_bytes(body).await.unwrap()).unwrap());
|
||||||
|
assert!(parts.status.is_success(), "Router answered with something else
|
||||||
|
than a success code.");
|
||||||
|
|
||||||
|
for ele in parts.headers.get_all(SET_COOKIE) {
|
||||||
|
let cookie = Cookie::parse(ele.to_str().unwrap()).unwrap();
|
||||||
|
self.cookies.push(format!("{}={}", cookie.name(), cookie.value()));
|
||||||
|
}
|
||||||
|
assert!(!self.cookies.is_empty(),
|
||||||
|
"No cookie detected on login, there should be an error.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Logout from the router.
|
||||||
|
pub async fn logout(&mut self) {
|
||||||
|
trace!("Logging out.");
|
||||||
|
let req = Request::builder()
|
||||||
|
.method(Method::POST)
|
||||||
|
.uri(format!("http://{}/ws", self.ip))
|
||||||
|
.header(COOKIE, self.cookies.join("; "))
|
||||||
|
.body(Body::empty())
|
||||||
|
.expect("Could not build request.");
|
||||||
|
|
||||||
|
self.client.request(req).await
|
||||||
|
.expect("There was an issue contacting the router.");
|
||||||
|
debug!("Logged out.");
|
||||||
|
self.cookies.clear();
|
||||||
|
self.context_id = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
12
src/lib.rs
12
src/lib.rs
@ -1,8 +1,4 @@
|
|||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
//! A crate aimed to gather (read only) data from a Livebox 4 or more recent.
|
||||||
#[test]
|
|
||||||
fn it_works() {
|
pub mod client;
|
||||||
let result = 2 + 2;
|
|
||||||
assert_eq!(result, 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user