2021-04-09 00:22:17 +00:00
|
|
|
use actix_web::{get, web, HttpResponse};
|
|
|
|
use regex::Regex;
|
2021-11-10 14:32:27 +00:00
|
|
|
use tokio_postgres::GenericClient;
|
2021-04-09 00:22:17 +00:00
|
|
|
|
|
|
|
use crate::activitypub::views::get_actor_url;
|
|
|
|
use crate::activitypub::constants::ACTIVITY_CONTENT_TYPE;
|
2021-11-10 14:32:27 +00:00
|
|
|
use crate::config::{Config, Instance};
|
2021-04-09 00:22:17 +00:00
|
|
|
use crate::database::{Pool, get_database_client};
|
2021-11-13 17:37:31 +00:00
|
|
|
use crate::errors::{HttpError, ValidationError};
|
2021-04-09 00:22:17 +00:00
|
|
|
use crate::models::users::queries::is_registered_user;
|
|
|
|
use super::types::{
|
|
|
|
JRD_CONTENT_TYPE,
|
|
|
|
WebfingerQueryParams,
|
|
|
|
Link,
|
|
|
|
JsonResourceDescriptor,
|
|
|
|
};
|
|
|
|
|
2021-11-07 08:52:57 +00:00
|
|
|
async fn get_user_info(
|
2021-11-10 14:32:27 +00:00
|
|
|
db_client: &impl GenericClient,
|
|
|
|
instance: Instance,
|
2021-04-09 00:22:17 +00:00
|
|
|
query_params: WebfingerQueryParams,
|
|
|
|
) -> Result<JsonResourceDescriptor, HttpError> {
|
|
|
|
// Parse 'acct' URI
|
|
|
|
// https://datatracker.ietf.org/doc/html/rfc7565#section-7
|
|
|
|
let uri_regexp = Regex::new(r"acct:(?P<user>\w+)@(?P<instance>.+)").unwrap();
|
|
|
|
let uri_caps = uri_regexp.captures(&query_params.resource)
|
2021-11-13 17:37:31 +00:00
|
|
|
.ok_or(ValidationError("invalid query target"))?;
|
2021-04-09 00:22:17 +00:00
|
|
|
let username = uri_caps.name("user")
|
2021-11-13 17:37:31 +00:00
|
|
|
.ok_or(ValidationError("invalid query target"))?
|
2021-04-09 00:22:17 +00:00
|
|
|
.as_str();
|
2021-11-10 14:32:27 +00:00
|
|
|
let instance_host = uri_caps.name("instance")
|
2021-11-13 17:37:31 +00:00
|
|
|
.ok_or(ValidationError("invalid query target"))?
|
2021-04-09 00:22:17 +00:00
|
|
|
.as_str();
|
|
|
|
|
2021-11-10 14:32:27 +00:00
|
|
|
if instance_host != instance.host() {
|
|
|
|
// Wrong instance
|
2021-04-09 00:22:17 +00:00
|
|
|
return Err(HttpError::NotFoundError("user"));
|
|
|
|
}
|
2021-11-13 17:37:31 +00:00
|
|
|
if !is_registered_user(db_client, username).await? {
|
2021-04-09 00:22:17 +00:00
|
|
|
return Err(HttpError::NotFoundError("user"));
|
|
|
|
}
|
2021-11-13 17:37:31 +00:00
|
|
|
let actor_url = get_actor_url(&instance.url(), username);
|
2021-04-09 00:22:17 +00:00
|
|
|
let link = Link {
|
|
|
|
rel: "self".to_string(),
|
|
|
|
link_type: Some(ACTIVITY_CONTENT_TYPE.to_string()),
|
|
|
|
href: Some(actor_url),
|
|
|
|
};
|
|
|
|
let jrd = JsonResourceDescriptor {
|
|
|
|
subject: query_params.resource,
|
|
|
|
links: vec![link],
|
|
|
|
};
|
|
|
|
Ok(jrd)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[get("/.well-known/webfinger")]
|
2021-11-07 08:52:57 +00:00
|
|
|
pub async fn get_descriptor(
|
2021-04-09 00:22:17 +00:00
|
|
|
config: web::Data<Config>,
|
2021-11-10 14:32:27 +00:00
|
|
|
db_pool: web::Data<Pool>,
|
2021-04-09 00:22:17 +00:00
|
|
|
query_params: web::Query<WebfingerQueryParams>,
|
|
|
|
) -> Result<HttpResponse, HttpError> {
|
2021-11-10 14:32:27 +00:00
|
|
|
let db_client = &**get_database_client(&db_pool).await?;
|
|
|
|
let jrd = get_user_info(
|
|
|
|
db_client,
|
|
|
|
config.instance(),
|
|
|
|
query_params.into_inner(),
|
|
|
|
).await?;
|
2021-04-09 00:22:17 +00:00
|
|
|
let response = HttpResponse::Ok()
|
|
|
|
.content_type(JRD_CONTENT_TYPE)
|
|
|
|
.json(jrd);
|
|
|
|
Ok(response)
|
|
|
|
}
|