libwallguard/
lib.rs

1use std::time::Duration;
2use tonic::transport::Channel;
3use tonic::Request;
4
5use crate::proto::wallguard::wall_guard_client::WallGuardClient;
6pub use crate::proto::wallguard::*;
7
8mod proto;
9
10#[derive(Clone)]
11pub struct WallGuardGrpcInterface {
12    client: WallGuardClient<Channel>,
13}
14
15// static CA_CERT: once_cell::sync::Lazy<Certificate> = once_cell::sync::Lazy::new(|| {
16//     Certificate::from_pem(
17//         std::fs::read_to_string("tls/ca.pem").expect("Failed to read CA certificate"),
18//     )
19// });
20
21impl WallGuardGrpcInterface {
22    #[allow(clippy::missing_panics_doc)]
23    pub async fn new(addr: &str, port: u16) -> Self {
24        // let tls = ClientTlsConfig::new().ca_certificate(CA_CERT.to_owned());
25        let s = format!("http://{addr}:{port}");
26
27        let Ok(channel) = Channel::from_shared(s)
28            .expect("Failed to parse address")
29            .timeout(Duration::from_secs(10))
30            // .tls_config(tls)
31            // .expect("Failed to configure up TLS")
32            .connect()
33            .await
34        else {
35            println!("Failed to connect to the server. Retrying in 10 seconds...");
36            tokio::time::sleep(std::time::Duration::from_secs(10)).await;
37            return Box::pin(WallGuardGrpcInterface::new(addr, port)).await;
38        };
39
40        Self {
41            client: WallGuardClient::new(channel).max_decoding_message_size(50 * 1024 * 1024),
42        }
43    }
44
45    #[allow(clippy::missing_errors_doc)]
46    pub async fn login(&mut self, app_id: String, app_secret: String) -> Result<String, String> {
47        let response = self
48            .client
49            .login(Request::new(LoginRequest { app_id, app_secret }))
50            .await
51            .map_err(|e| e.to_string())?;
52
53        Ok(response.into_inner().token)
54    }
55
56    #[allow(clippy::missing_errors_doc)]
57    pub async fn heartbeat(&mut self, token: String) -> Result<HeartbeatResponse, String> {
58        self.client
59            .heartbeat(Request::new(HeartbeatRequest {
60                auth: Some(Authentication { token }),
61            }))
62            .await
63            .map(tonic::Response::into_inner)
64            .map_err(|e| e.to_string())
65    }
66
67    #[allow(clippy::missing_errors_doc)]
68    pub async fn handle_packets(&mut self, message: Packets) -> Result<CommonResponse, String> {
69        self.client
70            .handle_packets(Request::new(message))
71            .await
72            .map(tonic::Response::into_inner)
73            .map_err(|e| e.to_string())
74    }
75
76    #[allow(clippy::missing_errors_doc)]
77    pub async fn handle_config(
78        &mut self,
79        message: ConfigSnapshot,
80    ) -> Result<CommonResponse, String> {
81        self.client
82            .handle_config(Request::new(message))
83            .await
84            .map(tonic::Response::into_inner)
85            .map_err(|e| e.to_string())
86    }
87
88    #[allow(clippy::missing_errors_doc)]
89    pub async fn setup_client(&mut self, request: SetupRequest) -> Result<CommonResponse, String> {
90        self.client
91            .setup(Request::new(request))
92            .await
93            .map(tonic::Response::into_inner)
94            .map_err(|e| e.to_string())
95    }
96
97    #[allow(clippy::missing_errors_doc)]
98    pub async fn device_status(&mut self, token: String) -> Result<StatusResponse, String> {
99        let response = self
100            .client
101            .status(Request::new(StatusRequest {
102                auth: Some(Authentication { token }),
103            }))
104            .await
105            .map(tonic::Response::into_inner)
106            .map_err(|e| e.to_string())?;
107
108        Ok(response)
109    }
110}