1pub mod auth;
2pub mod controller;
3pub mod device;
4pub mod responses;
5pub mod site;
6pub mod types;
7mod utils;
8
9use auth::sign_in;
10use reqwest::{cookie::Jar, Client};
11use site::types::Site;
12use std::sync::Arc;
13
14pub struct UnifiController {
15 cookie_store: Arc<Jar>,
18 client: Client,
19 sites: Vec<Site>,
20 pub current_site: Option<Site>,
21}
22
23impl UnifiController {
24 pub async fn new(
25 addr: String,
26 username: String,
27 password: String,
28 is_udm: bool,
29 ) -> Result<Self, Box<dyn std::error::Error>> {
30 let jar = Jar::default();
31 let cookie_store = Arc::new(jar);
32
33 let client = Client::builder()
34 .danger_accept_invalid_certs(true)
35 .user_agent("unifi-rs")
36 .cookie_store(true)
37 .cookie_provider(cookie_store.clone())
38 .build()?;
39
40 let mut api_root = addr.clone() + "/api";
41
42 if is_udm {
43 api_root = addr.clone() + "/proxy/network/api";
44 }
45
46 match sign_in(&client, &addr, username.clone(), password.clone(), is_udm).await {
47 Ok(_) => {}
48 Err(e) => return Err(e),
49 };
50
51 let sites = match controller::get_sites(&client, &cookie_store, api_root.clone()).await {
52 Ok(sites) => sites,
53 Err(e) => return Err(e),
54 };
55
56 Ok(UnifiController {
57 cookie_store,
59 client,
61 sites,
62 current_site: None,
63 })
64 }
65
66 pub fn get_sites(&self) -> Vec<Site> {
67 self.sites.clone()
68 }
69
70 pub fn set_site(&mut self, site_name: String) -> Result<(), Box<dyn std::error::Error>> {
71 for site in self.sites.clone() {
72 if site.name == site_name {
73 let mut new_site = site.clone();
74 new_site.set_active(self.client.clone(), &self.cookie_store);
75 self.current_site = Some(new_site);
76 return Ok(());
77 }
78 }
79 Err(Box::new(std::io::Error::new(
80 std::io::ErrorKind::NotFound,
81 "Site not found",
82 )))
83 }
84}