fix: webfinger accepts full ids
thanks ari for helping me debug this! <3
This commit is contained in:
parent
3fbff70933
commit
a4df9f2fc0
1 changed files with 51 additions and 35 deletions
|
@ -3,6 +3,8 @@ use jrd::{JsonResourceDescriptor, JsonResourceDescriptorLink};
|
||||||
use sea_orm::{ColumnTrait, EntityTrait, PaginatorTrait, QueryFilter};
|
use sea_orm::{ColumnTrait, EntityTrait, PaginatorTrait, QueryFilter};
|
||||||
use upub::{model, Context};
|
use upub::{model, Context};
|
||||||
|
|
||||||
|
use crate::ApiError;
|
||||||
|
|
||||||
#[derive(serde::Serialize)]
|
#[derive(serde::Serialize)]
|
||||||
pub struct NodeInfoDiscovery {
|
pub struct NodeInfoDiscovery {
|
||||||
pub links: Vec<NodeInfoDiscoveryRel>,
|
pub links: Vec<NodeInfoDiscoveryRel>,
|
||||||
|
@ -99,45 +101,59 @@ pub async fn webfinger(
|
||||||
State(ctx): State<Context>,
|
State(ctx): State<Context>,
|
||||||
Query(query): Query<WebfingerQuery>
|
Query(query): Query<WebfingerQuery>
|
||||||
) -> crate::ApiResult<JsonRD<JsonResourceDescriptor>> {
|
) -> crate::ApiResult<JsonRD<JsonResourceDescriptor>> {
|
||||||
if let Some((user, domain)) = query
|
let user =
|
||||||
.resource
|
if query.resource.starts_with("acct:") {
|
||||||
.replace("acct:", "")
|
if let Some((user, domain)) = query
|
||||||
.split_once('@')
|
.resource
|
||||||
{
|
.replace("acct:", "")
|
||||||
let usr = model::actor::Entity::find()
|
.split_once('@')
|
||||||
.filter(model::actor::Column::PreferredUsername.eq(user))
|
{
|
||||||
.filter(model::actor::Column::Domain.eq(domain))
|
model::actor::Entity::find()
|
||||||
.one(ctx.db())
|
.filter(model::actor::Column::PreferredUsername.eq(user))
|
||||||
.await?
|
.filter(model::actor::Column::Domain.eq(domain))
|
||||||
.ok_or_else(crate::ApiError::not_found)?;
|
.one(ctx.db())
|
||||||
|
.await?
|
||||||
|
.ok_or_else(crate::ApiError::not_found)?
|
||||||
|
|
||||||
let expires = if domain == ctx.domain() {
|
} else {
|
||||||
// TODO configurable webfinger TTL, also 30 days may be too much???
|
return Err(StatusCode::UNPROCESSABLE_ENTITY.into());
|
||||||
Some(chrono::Utc::now() + chrono::Duration::days(30))
|
}
|
||||||
|
} else if query.resource.starts_with("http") {
|
||||||
|
match model::actor::Entity::find_by_ap_id(&query.resource)
|
||||||
|
.one(ctx.db())
|
||||||
|
.await?
|
||||||
|
{
|
||||||
|
Some(usr) => usr,
|
||||||
|
None => return Err(ApiError::not_found()),
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// we are no authority on local users, this info should be considered already outdated,
|
return Err(StatusCode::UNPROCESSABLE_ENTITY.into());
|
||||||
// but can still be relevant, for example for our frontend
|
|
||||||
Some(chrono::Utc::now())
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(JsonRD(JsonResourceDescriptor {
|
let expires = if user.domain == ctx.domain() {
|
||||||
subject: format!("acct:{user}@{domain}"),
|
// TODO configurable webfinger TTL, also 30 days may be too much???
|
||||||
aliases: vec![usr.id.clone()],
|
Some(chrono::Utc::now() + chrono::Duration::days(30))
|
||||||
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(),
|
|
||||||
expires,
|
|
||||||
}))
|
|
||||||
} else {
|
} else {
|
||||||
Err(StatusCode::UNPROCESSABLE_ENTITY.into())
|
// we are no authority on local users, this info should be considered already outdated,
|
||||||
}
|
// but can still be relevant, for example for our frontend
|
||||||
|
Some(chrono::Utc::now())
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(JsonRD(JsonResourceDescriptor {
|
||||||
|
subject: format!("acct:{}@{}", user.preferred_username, user.domain),
|
||||||
|
aliases: vec![user.id.clone()],
|
||||||
|
links: vec![
|
||||||
|
JsonResourceDescriptorLink {
|
||||||
|
rel: "self".to_string(),
|
||||||
|
link_type: Some("application/ld+json".to_string()),
|
||||||
|
href: Some(user.id),
|
||||||
|
properties: jrd::Map::default(),
|
||||||
|
titles: jrd::Map::default(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
properties: jrd::Map::default(),
|
||||||
|
expires,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// i don't even want to bother with XML, im just returning a formatted xml string
|
// i don't even want to bother with XML, im just returning a formatted xml string
|
||||||
|
|
Loading…
Reference in a new issue