fix: resolve webfinger correctly

This commit is contained in:
aprilthepink 2024-07-17 14:21:32 +02:00
parent 071f6dcbd8
commit 692e4bff22
2 changed files with 29 additions and 21 deletions

View file

@ -4,7 +4,7 @@ use crate::{
error::Error, error::Error,
lysand::{ lysand::{
self, self,
conversion::{db_user_from_url, receive_lysand_note}, conversion::{db_user_from_url, local_db_user_from_name, receive_lysand_note},
}, },
objects::person::{DbUser, PersonAcceptedActivities}, objects::person::{DbUser, PersonAcceptedActivities},
utils::generate_user_id, utils::generate_user_id,
@ -107,26 +107,7 @@ pub async fn webfinger(
data: Data<StateHandle>, data: Data<StateHandle>,
) -> Result<HttpResponse, Error> { ) -> Result<HttpResponse, Error> {
let name = extract_webfinger_name(&query.resource, &data)?; let name = extract_webfinger_name(&query.resource, &data)?;
let db_user = data.read_user(name.clone()).await; let user = local_db_user_from_name(name.to_string()).await?;
let user;
if db_user.is_ok() {
user = db_user.unwrap();
} else {
let res = resolve("acct:".to_string() + name + "@" + &LYSAND_DOMAIN, true)
.await
.unwrap();
user = db_user_from_url(Url::parse(
res.links
.get(0)
.clone()
.unwrap()
.href
.clone()
.unwrap()
.as_str(),
)?)
.await?;
}
Ok(HttpResponse::Ok().json(build_webfinger_response( Ok(HttpResponse::Ok().json(build_webfinger_response(
query.resource.clone(), query.resource.clone(),
generate_user_id(&API_DOMAIN, &user.id)?, generate_user_id(&API_DOMAIN, &user.id)?,

View file

@ -4,6 +4,7 @@ use anyhow::{anyhow, Ok};
use async_recursion::async_recursion; use async_recursion::async_recursion;
use chrono::{DateTime, TimeZone, Utc}; use chrono::{DateTime, TimeZone, Utc};
use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set}; use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set};
use serde::{Deserialize, Serialize};
use time::OffsetDateTime; use time::OffsetDateTime;
use url::Url; use url::Url;
@ -167,6 +168,32 @@ pub async fn db_post_from_url(url: Url) -> anyhow::Result<entities::post::Model>
} }
} }
#[derive(Debug, Clone, Serialize, Deserialize)]
struct ApiUser {
uri: Url,
}
pub async fn local_db_user_from_name(name: String) -> anyhow::Result<entities::user::Model> {
let user_res: Option<user::Model> = prelude::User::find()
.filter(entities::user::Column::Username.eq(name.clone()))
.filter(entities::user::Column::Local.eq(true))
.one(DB.get().unwrap())
.await?;
if let Some(user) = user_res {
Ok(user)
} else {
let client = request_client();
let api_url = Url::parse(&format!(
"https://{}/api/v1/accounts/id?username={}",
LYSAND_DOMAIN.to_string(),
name
))?;
let request = client.get(api_url).send().await?;
let user_json = request.json::<ApiUser>().await?;
Ok(db_user_from_url(user_json.uri).await?)
}
}
pub async fn db_user_from_url(url: Url) -> anyhow::Result<entities::user::Model> { pub async fn db_user_from_url(url: Url) -> anyhow::Result<entities::user::Model> {
print!("Fetching user from domain: {}", url.domain().unwrap()); print!("Fetching user from domain: {}", url.domain().unwrap());
if !url.domain().eq(&Some(LYSAND_DOMAIN.as_str())) if !url.domain().eq(&Some(LYSAND_DOMAIN.as_str()))