2024-01-07 19:13:51 +01:00
|
|
|
use anyhow::anyhow;
|
|
|
|
use error::UbisyncError;
|
|
|
|
use reqwest::{Client, StatusCode};
|
2024-01-14 14:38:05 +01:00
|
|
|
use tracing::debug;
|
2024-01-07 19:13:51 +01:00
|
|
|
use ubisync_lib::api::{
|
2024-01-14 14:38:05 +01:00
|
|
|
app::{AppRegisterRequest, AppRegisterResponse, AppCreatePotRequest},
|
2024-01-07 19:13:51 +01:00
|
|
|
UbisyncRequest,
|
|
|
|
};
|
|
|
|
pub use ubisync_lib::*;
|
|
|
|
|
|
|
|
pub mod error;
|
|
|
|
|
|
|
|
pub struct UbisyncClient {
|
|
|
|
host: String,
|
|
|
|
port: u16,
|
|
|
|
selected_api_version: String,
|
|
|
|
base_url: String,
|
|
|
|
jwt_token: String,
|
|
|
|
reqwest_client: Client,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl UbisyncClient {
|
|
|
|
pub async fn init(
|
|
|
|
host: &str,
|
|
|
|
port: u16,
|
|
|
|
jwt_token: Option<&str>,
|
|
|
|
application_name: &str,
|
|
|
|
application_description: &str,
|
2024-01-14 14:38:05 +01:00
|
|
|
application_type: &str,
|
2024-01-07 19:13:51 +01:00
|
|
|
) -> Result<Self, UbisyncError> {
|
|
|
|
let http_client = Client::new();
|
|
|
|
let mut node_api_versions = http_client
|
|
|
|
.get(&format!("http://{}:{}/versions", host, port))
|
|
|
|
.send()
|
|
|
|
.await
|
|
|
|
.expect("Failed to contact ubisync node, it may be offline.")
|
|
|
|
.json::<Vec<String>>()
|
|
|
|
.await
|
|
|
|
.expect("Failed to read ubisync node's available API versions.");
|
|
|
|
|
|
|
|
node_api_versions.sort();
|
|
|
|
let selected_version = node_api_versions
|
|
|
|
.get(0)
|
|
|
|
.expect("No available API version returned by ubisync node");
|
|
|
|
|
|
|
|
let token = match jwt_token {
|
|
|
|
Some(t) => t.to_string(),
|
|
|
|
None => {
|
|
|
|
let response = http_client
|
|
|
|
.put(Self::build_base_url(host, port, &selected_version) + "/app/register")
|
|
|
|
.json(&AppRegisterRequest {
|
|
|
|
name: application_name.to_string(),
|
|
|
|
description: application_description.to_string(),
|
2024-01-14 14:38:05 +01:00
|
|
|
app_type: application_type.to_string(),
|
2024-01-07 19:13:51 +01:00
|
|
|
})
|
|
|
|
.send()
|
|
|
|
.await
|
|
|
|
.expect("App registration request failed.");
|
|
|
|
if response.status() != StatusCode::OK {
|
|
|
|
return Err(UbisyncError::AppRegistrationFailed);
|
|
|
|
}
|
|
|
|
response
|
|
|
|
.json::<AppRegisterResponse>()
|
|
|
|
.await
|
|
|
|
.expect("Failed to extract JWT from app regstration request")
|
|
|
|
.token
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
Ok(UbisyncClient {
|
|
|
|
host: host.to_string(),
|
|
|
|
port: port,
|
|
|
|
selected_api_version: selected_version.to_string(),
|
|
|
|
base_url: Self::build_base_url(host, port, selected_version),
|
|
|
|
jwt_token: token.to_string(),
|
|
|
|
reqwest_client: http_client,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2024-01-14 14:38:05 +01:00
|
|
|
pub async fn create_default_pot(self) -> anyhow::Result<UbisyncClient> {
|
|
|
|
let response = self.send(AppCreatePotRequest {
|
|
|
|
app_type: None,
|
|
|
|
}, ()).await?;
|
|
|
|
debug!("Created new pot with ID {:?}", response.pot_id);
|
|
|
|
Ok(self)
|
|
|
|
}
|
|
|
|
|
2024-01-07 19:13:51 +01:00
|
|
|
pub async fn send<R>(
|
|
|
|
&self,
|
|
|
|
request: R,
|
|
|
|
parameters: R::PathParameters,
|
|
|
|
) -> anyhow::Result<R::Response>
|
|
|
|
where
|
|
|
|
R: UbisyncRequest,
|
|
|
|
{
|
|
|
|
self.reqwest_client
|
|
|
|
.request(
|
|
|
|
request.method(),
|
|
|
|
&(self.base_url.to_owned() + &request.path(parameters)),
|
|
|
|
)
|
|
|
|
.bearer_auth(&self.jwt_token)
|
|
|
|
.json(&request)
|
|
|
|
.send()
|
|
|
|
.await
|
|
|
|
.map_err(|e| anyhow!(e))?
|
|
|
|
.json::<R::Response>()
|
|
|
|
.await
|
|
|
|
.map_err(|e| anyhow!(e))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn set_host(&mut self, host: String) {
|
|
|
|
self.host = host;
|
|
|
|
self.base_url = Self::build_base_url(&self.host, self.port, &self.selected_api_version);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn set_port(&mut self, port: u16) {
|
|
|
|
self.port = port;
|
|
|
|
self.base_url = Self::build_base_url(&self.host, self.port, &self.selected_api_version);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn set_api_version(&mut self, version: String) {
|
|
|
|
self.selected_api_version = version;
|
|
|
|
self.base_url = Self::build_base_url(&self.host, self.port, &self.selected_api_version);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn build_base_url(host: &str, port: u16, api_version: &str) -> String {
|
|
|
|
format!("http://{}:{}/{}", host, port, api_version)
|
|
|
|
}
|
|
|
|
}
|