Compare commits

..

No commits in common. "ebb7d77cae3b88cdee02f864cbf9f4ffc4b4dcc1" and "a2812ebf15a3c88dfb66ba666a4802624e8a04ad" have entirely different histories.

2 changed files with 37 additions and 65 deletions

View file

@ -1,4 +1,4 @@
use crate::Object; use crate::{Object, Link};
pub const PUBLIC : &str = "https://www.w3.org/ns/activitystreams#Public"; pub const PUBLIC : &str = "https://www.w3.org/ns/activitystreams#Public";

View file

@ -1,8 +1,8 @@
use axum::{extract::{Path, Query, State}, http::StatusCode, response::{IntoResponse, Response}, Json}; use axum::{extract::{Path, Query, State}, http::StatusCode, response::{IntoResponse, Response}, Json};
use jrd::{JsonResourceDescriptor, JsonResourceDescriptorLink}; use jrd::{JsonResourceDescriptor, JsonResourceDescriptorLink};
use sea_orm::{ColumnTrait, EntityTrait, PaginatorTrait, QueryFilter}; use sea_orm::{EntityTrait, PaginatorTrait};
use crate::{errors::UpubError, model, server::Context, url, VERSION}; use crate::{model, server::Context, url, VERSION};
#[derive(serde::Serialize)] #[derive(serde::Serialize)]
pub struct NodeInfoDiscovery { pub struct NodeInfoDiscovery {
@ -96,85 +96,57 @@ impl<T: serde::Serialize> IntoResponse for JsonRD<T> {
} }
} }
pub async fn webfinger(State(ctx): State<Context>, Query(query): Query<WebfingerQuery>) -> crate::Result<JsonRD<JsonResourceDescriptor>> { pub async fn webfinger(State(ctx): State<Context>, Query(query): Query<WebfingerQuery>) -> Result<JsonRD<JsonResourceDescriptor>, StatusCode> {
if let Some((user, domain)) = query if let Some((user, domain)) = query
.resource .resource
.replace("acct:", "") .replace("acct:", "")
.split_once('@') .split_once('@')
{ {
if domain == ctx.domain() { if user == ctx.domain() && domain == ctx.domain() {
if user == ctx.domain() { return Ok(JsonRD(JsonResourceDescriptor {
// we fetch with our domain as user, they are checking us back, this is a special edge case
Ok(JsonRD(JsonResourceDescriptor {
subject: format!("acct:{user}@{domain}"),
aliases: vec![ctx.base().to_string()],
links: vec![
JsonResourceDescriptorLink {
rel: "self".to_string(),
link_type: Some("application/ld+json".to_string()),
href: Some(ctx.base().to_string()),
properties: jrd::Map::default(),
titles: jrd::Map::default(),
},
],
expires: None,
properties: jrd::Map::default(),
}))
} else {
// local user
let uid = ctx.uid(user);
let usr = model::user::Entity::find_by_id(uid)
.one(ctx.db())
.await?
.ok_or_else(UpubError::not_found)?;
Ok(JsonRD(JsonResourceDescriptor {
subject: format!("acct:{user}@{domain}"),
aliases: vec![usr.id.clone()],
links: vec![
JsonResourceDescriptorLink {
rel: "self".to_string(),
link_type: Some("application/ld+json".to_string()),
href: Some(usr.id),
properties: jrd::Map::default(),
titles: jrd::Map::default(),
},
],
expires: None,
properties: jrd::Map::default(),
}))
}
} else {
// remote user
let usr = model::user::Entity::find()
.filter(model::user::Column::PreferredUsername.eq(user))
.filter(model::user::Column::Domain.eq(domain))
.one(ctx.db())
.await?
.ok_or_else(UpubError::not_found)?;
Ok(JsonRD(JsonResourceDescriptor {
subject: format!("acct:{user}@{domain}"), subject: format!("acct:{user}@{domain}"),
aliases: vec![usr.id.clone()], aliases: vec![ctx.base().to_string()],
links: vec![ links: vec![
JsonResourceDescriptorLink { JsonResourceDescriptorLink {
rel: "self".to_string(), rel: "self".to_string(),
link_type: Some("application/ld+json".to_string()), link_type: Some("application/ld+json".to_string()),
href: Some(usr.id), href: Some(ctx.base().to_string()),
properties: jrd::Map::default(), properties: jrd::Map::default(),
titles: jrd::Map::default(), titles: jrd::Map::default(),
}, },
], ],
expires: None,
properties: jrd::Map::default(), properties: jrd::Map::default(),
// we are no authority on local users, this info should be considered already outdated, }));
// but can still be relevant, for example for our frontend }
expires: Some(chrono::Utc::now()), let uid = ctx.uid(user);
})) match model::user::Entity::find_by_id(uid)
.one(ctx.db())
.await
{
Ok(Some(x)) => Ok(JsonRD(JsonResourceDescriptor {
subject: format!("acct:{user}@{domain}"),
aliases: vec![x.id.clone()],
links: vec![
JsonResourceDescriptorLink {
rel: "self".to_string(),
link_type: Some("application/ld+json".to_string()),
href: Some(x.id),
properties: jrd::Map::default(),
titles: jrd::Map::default(),
},
],
expires: None,
properties: jrd::Map::default(),
})),
Ok(None) => Err(StatusCode::NOT_FOUND),
Err(e) => {
tracing::error!("error executing webfinger query: {e}");
Err(StatusCode::INTERNAL_SERVER_ERROR)
},
} }
} else { } else {
Err(StatusCode::UNPROCESSABLE_ENTITY.into()) Err(StatusCode::UNPROCESSABLE_ENTITY)
} }
} }