pub mod services;
use std::{error, fmt};
use bytes::Bytes;
use hyper::{client::Client as HyperClient, client::HttpConnector, http::uri::InvalidUri};
use hyper_tls::HttpsConnector;
use secp256k1::key::PublicKey;
use thiserror::Error;
use tower_service::Service;
use tower_util::ServiceExt;
use crate::models::*;
use services::*;
#[derive(Debug, Error)]
pub enum KeyserverError<E: fmt::Display + error::Error + 'static> {
#[error(transparent)]
Uri(InvalidUri),
#[error("failed to execute service method: {0}")]
Error(#[from] E),
}
#[derive(Clone, Debug)]
pub struct MetadataPackage {
pub token: String,
pub public_key: PublicKey,
pub metadata: AddressMetadata,
pub raw_auth_wrapper: Bytes,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RawAuthWrapperPackage {
pub token: String,
pub raw_auth_wrapper: Bytes,
}
#[derive(Clone, Debug)]
pub struct KeyserverClient<S> {
inner_client: S,
}
impl<S> KeyserverClient<S> {
pub fn from_service(service: S) -> Self {
Self {
inner_client: service,
}
}
}
impl Default for KeyserverClient<HyperClient<HttpConnector>> {
fn default() -> Self {
Self {
inner_client: HyperClient::new(),
}
}
}
impl KeyserverClient<HyperClient<HttpConnector>> {
pub fn new() -> Self {
Default::default()
}
}
impl KeyserverClient<HyperClient<HttpsConnector<HttpConnector>>> {
pub fn new_tls() -> Self {
let https = HttpsConnector::new();
Self {
inner_client: HyperClient::builder().build(https),
}
}
}
impl<S> KeyserverClient<S>
where
Self: Service<(Uri, GetPeers), Response = Peers>,
Self: Sync + Clone + Send + 'static,
<Self as Service<(Uri, GetPeers)>>::Error: fmt::Display + std::error::Error,
<Self as Service<(Uri, GetPeers)>>::Future: Send + Sync + 'static,
{
pub async fn get_peers(
&self,
keyserver_url: &str,
) -> Result<Peers, KeyserverError<<Self as Service<(Uri, GetPeers)>>::Error>> {
let full_path = format!("{}/peers", keyserver_url);
let uri: Uri = full_path.parse().map_err(KeyserverError::Uri)?;
let request = (uri, GetPeers);
self.clone()
.oneshot(request)
.await
.map_err(KeyserverError::Error)
}
}
impl<S> KeyserverClient<S>
where
Self: Service<(Uri, GetMetadata), Response = MetadataPackage>,
Self: Sync + Clone + Send + 'static,
<Self as Service<(Uri, GetMetadata)>>::Error: fmt::Display + std::error::Error,
<Self as Service<(Uri, GetMetadata)>>::Future: Send + Sync + 'static,
{
pub async fn get_metadata(
&self,
keyserver_url: &str,
address: &str,
) -> Result<MetadataPackage, KeyserverError<<Self as Service<(Uri, GetMetadata)>>::Error>> {
let full_path = format!("{}/keys/{}", keyserver_url, address);
let uri: Uri = full_path.parse().map_err(KeyserverError::Uri)?;
let request = (uri, GetMetadata);
self.clone()
.oneshot(request)
.await
.map_err(KeyserverError::Error)
}
}
impl<S> KeyserverClient<S>
where
Self: Service<(Uri, PutMetadata), Response = ()>,
Self: Sync + Clone + Send + 'static,
<Self as Service<(Uri, PutMetadata)>>::Error: fmt::Display + std::error::Error,
<Self as Service<(Uri, PutMetadata)>>::Future: Send + Sync + 'static,
{
pub async fn put_metadata(
&self,
keyserver_url: &str,
address: &str,
auth_wrapper: AuthWrapper,
token: String,
) -> Result<(), KeyserverError<<Self as Service<(Uri, PutMetadata)>>::Error>> {
let full_path = format!("{}/keys/{}", keyserver_url, address);
let uri: Uri = full_path.parse().map_err(KeyserverError::Uri)?;
let request = (
uri,
PutMetadata {
token,
auth_wrapper,
},
);
self.clone()
.oneshot(request)
.await
.map_err(KeyserverError::Error)
}
}
impl<S> KeyserverClient<S>
where
Self: Service<(Uri, PutRawAuthWrapper), Response = ()>,
Self: Sync + Clone + Send + 'static,
<Self as Service<(Uri, PutRawAuthWrapper)>>::Error: std::error::Error,
<Self as Service<(Uri, PutRawAuthWrapper)>>::Future: Send + Sync + 'static,
{
pub async fn put_raw_metadata(
&self,
keyserver_url: &str,
address: &str,
raw_auth_wrapper: Vec<u8>,
token: String,
) -> Result<(), KeyserverError<<Self as Service<(Uri, PutRawAuthWrapper)>>::Error>> {
let full_path = format!("{}/keys/{}", keyserver_url, address);
let uri: Uri = full_path.parse().map_err(KeyserverError::Uri)?;
let request = (
uri,
PutRawAuthWrapper {
token,
raw_auth_wrapper,
},
);
self.clone()
.oneshot(request)
.await
.map_err(KeyserverError::Error)
}
}