103 lines
2.8 KiB
Rust
103 lines
2.8 KiB
Rust
use std::{io::Cursor, sync::Arc};
|
|
|
|
use client::federation_client::{FederationClient, FederationClientError};
|
|
use magnetar_common::{config::MagnetarNetworkingProtocol, util::FediverseTag};
|
|
use magnetar_host_meta::{Xrd, XrdXml};
|
|
use magnetar_webfinger::webfinger::WebFinger;
|
|
use serde::{Deserialize, Serialize};
|
|
use url::Url;
|
|
|
|
pub mod client;
|
|
|
|
/// The *visible* domain of fediverse handles, that gets resolved by WebFinger
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
#[serde(transparent)]
|
|
pub struct HostUnmapped(String);
|
|
|
|
/// The real domain of fediverse handles used for federation
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
#[serde(transparent)]
|
|
pub struct HostMapped(String);
|
|
|
|
pub trait HostMetaResolverService {
|
|
type Error;
|
|
|
|
async fn resolve(&self, host: &HostUnmapped) -> Result<Xrd, Self::Error>;
|
|
}
|
|
|
|
pub struct HostMetaResolverProviderDefault {
|
|
client: Arc<FederationClient>,
|
|
protocol: MagnetarNetworkingProtocol,
|
|
}
|
|
|
|
impl HostMetaResolverService for HostMetaResolverProviderDefault {
|
|
type Error = FederationClientError;
|
|
|
|
async fn resolve(&self, HostUnmapped(host): &HostUnmapped) -> Result<Xrd, Self::Error> {
|
|
let host_meta_xml = self
|
|
.client
|
|
.get(Url::parse(&format!(
|
|
"{}://{}/.well-known/host-meta",
|
|
self.protocol.as_ref(),
|
|
host
|
|
))?)
|
|
.send()
|
|
.await?;
|
|
|
|
let XrdXml::Xrd(xrd) = quick_xml::de::from_reader(Cursor::new(host_meta_xml))?;
|
|
|
|
Ok(xrd)
|
|
}
|
|
}
|
|
|
|
pub trait WebFingerResolverService {
|
|
type Error;
|
|
|
|
async fn resolve_url(&self, url: &str) -> Result<WebFinger, Self::Error>;
|
|
|
|
async fn resolve(
|
|
&self,
|
|
template_url: &str,
|
|
resolved_uri: &str,
|
|
) -> Result<WebFinger, Self::Error> {
|
|
self.resolve_url(
|
|
&template_url.replace(
|
|
"{}",
|
|
&percent_encoding::utf8_percent_encode(
|
|
resolved_uri,
|
|
percent_encoding::NON_ALPHANUMERIC,
|
|
)
|
|
.to_string(),
|
|
),
|
|
)
|
|
.await
|
|
}
|
|
}
|
|
|
|
pub struct WebFingerResolverProviderDefault {
|
|
client: Arc<FederationClient>,
|
|
}
|
|
|
|
impl WebFingerResolverService for WebFingerResolverProviderDefault {
|
|
type Error = FederationClientError;
|
|
|
|
async fn resolve_url(&self, url: &str) -> Result<WebFinger, Self::Error> {
|
|
let host_meta_xml = self.client.get(Url::parse(url)?).send().await?;
|
|
let webfinger = serde_json::from_reader(Cursor::new(host_meta_xml))?;
|
|
Ok(webfinger)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct MappedUser {
|
|
pub host_meta: Xrd,
|
|
pub webfinger: WebFinger,
|
|
pub tag_mapped: FediverseTag,
|
|
}
|
|
|
|
pub trait FederationService {
|
|
type Error;
|
|
|
|
async fn map_fedi_tag(&self, host: &HostUnmapped) -> Result<MappedUser, Self::Error>;
|
|
}
|