Compare commits
2 commits
a2812ebf15
...
ebb7d77cae
Author | SHA1 | Date | |
---|---|---|---|
ebb7d77cae | |||
e146dc2a51 |
2 changed files with 65 additions and 37 deletions
|
@ -1,4 +1,4 @@
|
||||||
use crate::{Object, Link};
|
use crate::Object;
|
||||||
|
|
||||||
pub const PUBLIC : &str = "https://www.w3.org/ns/activitystreams#Public";
|
pub const PUBLIC : &str = "https://www.w3.org/ns/activitystreams#Public";
|
||||||
|
|
||||||
|
|
|
@ -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::{EntityTrait, PaginatorTrait};
|
use sea_orm::{ColumnTrait, EntityTrait, PaginatorTrait, QueryFilter};
|
||||||
|
|
||||||
use crate::{model, server::Context, url, VERSION};
|
use crate::{errors::UpubError, model, server::Context, url, VERSION};
|
||||||
|
|
||||||
#[derive(serde::Serialize)]
|
#[derive(serde::Serialize)]
|
||||||
pub struct NodeInfoDiscovery {
|
pub struct NodeInfoDiscovery {
|
||||||
|
@ -96,14 +96,16 @@ impl<T: serde::Serialize> IntoResponse for JsonRD<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn webfinger(State(ctx): State<Context>, Query(query): Query<WebfingerQuery>) -> Result<JsonRD<JsonResourceDescriptor>, StatusCode> {
|
pub async fn webfinger(State(ctx): State<Context>, Query(query): Query<WebfingerQuery>) -> crate::Result<JsonRD<JsonResourceDescriptor>> {
|
||||||
if let Some((user, domain)) = query
|
if let Some((user, domain)) = query
|
||||||
.resource
|
.resource
|
||||||
.replace("acct:", "")
|
.replace("acct:", "")
|
||||||
.split_once('@')
|
.split_once('@')
|
||||||
{
|
{
|
||||||
if user == ctx.domain() && domain == ctx.domain() {
|
if domain == ctx.domain() {
|
||||||
return Ok(JsonRD(JsonResourceDescriptor {
|
if user == ctx.domain() {
|
||||||
|
// 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}"),
|
subject: format!("acct:{user}@{domain}"),
|
||||||
aliases: vec![ctx.base().to_string()],
|
aliases: vec![ctx.base().to_string()],
|
||||||
links: vec![
|
links: vec![
|
||||||
|
@ -117,36 +119,62 @@ pub async fn webfinger(State(ctx): State<Context>, Query(query): Query<Webfinger
|
||||||
],
|
],
|
||||||
expires: None,
|
expires: None,
|
||||||
properties: jrd::Map::default(),
|
properties: jrd::Map::default(),
|
||||||
}));
|
}))
|
||||||
}
|
|
||||||
|
} else {
|
||||||
|
// local user
|
||||||
let uid = ctx.uid(user);
|
let uid = ctx.uid(user);
|
||||||
match model::user::Entity::find_by_id(uid)
|
let usr = model::user::Entity::find_by_id(uid)
|
||||||
.one(ctx.db())
|
.one(ctx.db())
|
||||||
.await
|
.await?
|
||||||
{
|
.ok_or_else(UpubError::not_found)?;
|
||||||
Ok(Some(x)) => Ok(JsonRD(JsonResourceDescriptor {
|
|
||||||
|
Ok(JsonRD(JsonResourceDescriptor {
|
||||||
subject: format!("acct:{user}@{domain}"),
|
subject: format!("acct:{user}@{domain}"),
|
||||||
aliases: vec![x.id.clone()],
|
aliases: vec![usr.id.clone()],
|
||||||
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(x.id),
|
href: Some(usr.id),
|
||||||
properties: jrd::Map::default(),
|
properties: jrd::Map::default(),
|
||||||
titles: jrd::Map::default(),
|
titles: jrd::Map::default(),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
expires: None,
|
expires: None,
|
||||||
properties: jrd::Map::default(),
|
properties: jrd::Map::default(),
|
||||||
})),
|
}))
|
||||||
Ok(None) => Err(StatusCode::NOT_FOUND),
|
}
|
||||||
Err(e) => {
|
|
||||||
tracing::error!("error executing webfinger query: {e}");
|
} else {
|
||||||
Err(StatusCode::INTERNAL_SERVER_ERROR)
|
// 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}"),
|
||||||
|
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(),
|
||||||
},
|
},
|
||||||
|
],
|
||||||
|
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()),
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(StatusCode::UNPROCESSABLE_ENTITY)
|
Err(StatusCode::UNPROCESSABLE_ENTITY.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue