use super::{constants::SN_AUTHD_CONNECTION_IDLE_TIMEOUT, Error, Result};
use log::info;
use qjsonrpc::ClientEndpoint;
use serde::de::DeserializeOwned;
use std::path::Path;
use tokio::runtime;
pub mod auth_types {
use crate::ipc::req::IpcReq;
use serde::{Deserialize, Serialize};
pub type SafeAuthReq = IpcReq;
pub type SafeAuthReqId = u32;
#[derive(Debug, Serialize, Deserialize)]
pub struct AuthedApp {
pub id: String,
pub name: String,
pub vendor: String,
}
pub type AuthedAppsList = Vec<AuthedApp>;
}
pub async fn send_authd_request<T>(
cert_path: &Path,
dst_endpoint: &str,
method: &str,
params: serde_json::Value,
) -> Result<T>
where
T: DeserializeOwned,
{
info!(
"Sending '{}' request to SAFE Authenticator on {} ...",
method, dst_endpoint
);
let qjsonrpc_client =
ClientEndpoint::new(cert_path, Some(SN_AUTHD_CONNECTION_IDLE_TIMEOUT), false).map_err(
|err| Error::AuthdClientError(format!("Failed to create client endpoint: {err}")),
)?;
let runtime = match runtime::Handle::try_current() {
Ok(r) => r,
Err(_) => runtime::Runtime::new()
.map_err(|err| Error::AuthdClientError(format!("Failed to create runtime: {err}")))?
.handle()
.clone(),
};
let mut outgoing_conn = {
let _ = runtime.enter();
qjsonrpc_client
.bind()
.map_err(|err| Error::AuthdClientError(format!("Failed to bind endpoint: {err}")))?
};
outgoing_conn
.connect(dst_endpoint, None)
.await
.map_err(|err| {
Error::AuthdClientError(format!("Failed to establish connection with authd: {err}",))
})?
.send(method, params)
.await
.map_err(|err| match err {
qjsonrpc::Error::RemoteEndpointError(msg) => Error::AuthdError(msg),
other => Error::AuthdClientError(other.to_string()),
})
}