asonix
e0858b7b3d
Currently i18n'd - login page - register page - cookie page - delete account confirmation page - 404 page - 500 page - part of account settings
96 lines
3.4 KiB
Rust
96 lines
3.4 KiB
Rust
use crate::{error::OptionExt, State};
|
|
use actix_web::{error::ResponseError, http::StatusCode, web, HttpResponse};
|
|
use actix_webfinger::{Resolver, Webfinger};
|
|
use futures::future::LocalBoxFuture;
|
|
use rsa::RSAPublicKey;
|
|
use rsa_magic_public_key::AsMagicPublicKey;
|
|
use rsa_pem::KeyExt;
|
|
|
|
pub(super) struct HyaenidaeResolver;
|
|
|
|
#[derive(Clone, Debug, thiserror::Error)]
|
|
#[error("Error resolving webfinger data")]
|
|
pub(super) struct ResolveError;
|
|
|
|
impl Resolver for HyaenidaeResolver {
|
|
type State = web::Data<State>;
|
|
type Error = ResolveError;
|
|
|
|
fn find(
|
|
handle: &str,
|
|
domain: &str,
|
|
state: Self::State,
|
|
) -> LocalBoxFuture<'static, Result<Option<Webfinger>, Self::Error>> {
|
|
let handle = handle.to_owned();
|
|
let domain = domain.to_owned();
|
|
|
|
Box::pin(async move {
|
|
if domain != state.domain {
|
|
return Ok(None);
|
|
}
|
|
|
|
let mut wf = Webfinger::new(&format!("{}@{}", handle, domain));
|
|
|
|
let wf = if handle == domain {
|
|
let server_store = state.profiles.store.servers.clone();
|
|
let apub_store = state.profiles.apub.clone();
|
|
|
|
web::block(move || {
|
|
let self_id = server_store.get_self()?.req()?;
|
|
let apub_id = apub_store.apub_for_server(self_id)?.req()?;
|
|
let key_id = apub_store.key_for_server(self_id)?.req()?;
|
|
let public_key = apub_store.public_key_for_id(&key_id)?.req()?;
|
|
let key = RSAPublicKey::from_pem_pkcs8(&public_key)?;
|
|
|
|
wf.add_activitypub(apub_id.as_str())
|
|
.add_magic_public_key(&key.as_magic_public_key());
|
|
|
|
Ok(wf) as Result<_, anyhow::Error>
|
|
})
|
|
.await
|
|
.map_err(|e| {
|
|
log::error!("Failed to find server actor: {}", e);
|
|
ResolveError
|
|
})?
|
|
} else {
|
|
let profile_store = state.profiles.store.profiles.clone();
|
|
let apub_store = state.profiles.apub.clone();
|
|
|
|
web::block(move || {
|
|
let profile_id = profile_store.by_handle(&handle, &domain)?.req()?;
|
|
let apub_id = apub_store.apub_for_profile(profile_id)?.req()?;
|
|
let key_id = apub_store.key_for_profile(profile_id)?.req()?;
|
|
let public_key = apub_store.public_key_for_id(&key_id)?.req()?;
|
|
let key = RSAPublicKey::from_pem_pkcs8(&public_key)?;
|
|
|
|
let mut profile_url = apub_id.clone();
|
|
profile_url.set_path(&format!("/profiles/@{}@{}", handle, domain));
|
|
|
|
wf.add_activitypub(apub_id.as_str())
|
|
.add_magic_public_key(&key.as_magic_public_key())
|
|
.add_profile(profile_url.as_str());
|
|
|
|
Ok(wf) as Result<_, anyhow::Error>
|
|
})
|
|
.await
|
|
.map_err(|e| {
|
|
log::error!("Failed to find profile actor: {}", e);
|
|
ResolveError
|
|
})?
|
|
};
|
|
|
|
Ok(Some(wf))
|
|
})
|
|
}
|
|
}
|
|
|
|
impl ResponseError for ResolveError {
|
|
fn status_code(&self) -> StatusCode {
|
|
StatusCode::NOT_FOUND
|
|
}
|
|
|
|
fn error_response(&self) -> HttpResponse {
|
|
HttpResponse::NotFound().finish()
|
|
}
|
|
}
|