lemmy/crates/routes/src/webfinger.rs

112 lines
3.1 KiB
Rust
Raw Normal View History

2023-04-05 20:29:08 +00:00
use activitypub_federation::{
config::Data,
fetch::webfinger::{extract_webfinger_name, Webfinger, WebfingerLink},
};
use actix_web::{web, web::Query, HttpResponse};
use lemmy_api_common::context::LemmyContext;
use lemmy_db_schema::{
source::{community::Community, person::Person},
traits::ApubActor,
};
use lemmy_utils::{cache_header::cache_3days, error::LemmyError};
use serde::Deserialize;
use std::collections::HashMap;
2021-11-16 17:03:09 +00:00
use url::Url;
2019-12-18 00:59:47 +00:00
#[derive(Deserialize)]
struct Params {
2019-12-18 00:59:47 +00:00
resource: String,
}
pub fn config(cfg: &mut web::ServiceConfig) {
cfg.route(
".well-known/webfinger",
web::get().to(get_webfinger_response).wrap(cache_3days()),
);
}
2019-12-18 00:59:47 +00:00
/// Responds to webfinger requests of the following format. There isn't any real documentation for
/// this, but it described in this blog post:
/// https://mastodon.social/.well-known/webfinger?resource=acct:gargron@mastodon.social
///
/// You can also view the webfinger response that Mastodon sends:
/// https://radical.town/.well-known/webfinger?resource=acct:felix@radical.town
async fn get_webfinger_response(
info: Query<Params>,
2023-04-05 20:29:08 +00:00
context: Data<LemmyContext>,
) -> Result<HttpResponse, LemmyError> {
2023-04-05 20:29:08 +00:00
let name = extract_webfinger_name(&info.resource, &context)?;
2019-12-18 00:59:47 +00:00
2021-11-16 17:03:09 +00:00
let name_ = name.clone();
Make functions work with both connection and pool (#3420) * a lot * merge * Fix stuff broken by merge * Get rid of repetitive `&mut *context.conn().await?` * Add blank lines under each line with `conn =` * Fix style mistakes (partial) * Revert "Fix style mistakes (partial)" This reverts commit 48a033b87f4fdc1ce14ff86cc019e1c703cd2741. * Revert "Add blank lines under each line with `conn =`" This reverts commit 773a6d3beba2cf89eac75913078b40c4f5190dd4. * Revert "Get rid of repetitive `&mut *context.conn().await?`" This reverts commit d2c6263ea13710177d49b2791278db5ad115fca5. * Use DbConn for CaptchaAnswer methods * DbConn trait * Remove more `&mut *` * Fix stuff * Re-run CI * try to make ci start * fix * fix * Fix api_common::utils * Fix apub::activities::block * Fix apub::api::resolve_object * Fix some things * Revert "Fix some things" This reverts commit 2bf8574bc8333d8d34ca542d61a0a5b50039c24d. * Revert "Fix apub::api::resolve_object" This reverts commit 3e4059aabbe485b2ff060bdeced8ef958ff62832. * Revert "Fix apub::activities::block" This reverts commit 3b02389abd780a7b1b8a2c89e26febdaa6a12159. * Revert "Fix api_common::utils" This reverts commit 7dc73de613a5618fa57eb06450f3699bbcb41254. * Revert "Revert "Fix api_common::utils"" This reverts commit f740f115e5457e83e53cc223e48196a2c47a9975. * Revert "Revert "Fix apub::activities::block"" This reverts commit 2ee206af7c885c10092cf209bf4a5b1d60327866. * Revert "Revert "Fix apub::api::resolve_object"" This reverts commit 96ed8bf2e9dcadae760743929498312334e23d2e. * Fix fetch_local_site_data * Fix get_comment_parent_creator * Remove unused perma deleted text * Fix routes::feeds * Fix lib.rs * Update lib.rs * rerun ci * Attempt to create custom GetConn and RunQueryDsl traits * Start over * Add GetConn trait * aaaa * Revert "aaaa" This reverts commit acc9ca1aed10c39efdd91cefece066e035a1fe80. * Revert "Revert "aaaa"" This reverts commit 443a2a00a56d152bb7eb429efd0d29a78e21b163. * still aaaaaaaaaaaaa * Return to earlier thing Revert "Add GetConn trait" This reverts commit ab4e94aea5bd9d34cbcddf017339131047e75344. * Try to use DbPool enum * Revert "Try to use DbPool enum" This reverts commit e4d1712646a52006b865a1fbe0dcf79976fdb027. * DbConn and DbPool enums (db_schema only fails to compile for tests) * fmt * Make functions take `&mut DbPool<'_>` and make db_schema tests compile * Add try_join_with_pool macro and run fix-clippy on more crates * Fix some errors * I did it * Remove function variants that take connection * rerun ci * rerun ci * rerun ci
2023-07-11 13:09:59 +00:00
let user_id: Option<Url> = Person::read_from_name(&mut context.pool(), &name_, false)
2022-11-09 10:05:00 +00:00
.await
.ok()
.map(|c| c.actor_id.into());
Make functions work with both connection and pool (#3420) * a lot * merge * Fix stuff broken by merge * Get rid of repetitive `&mut *context.conn().await?` * Add blank lines under each line with `conn =` * Fix style mistakes (partial) * Revert "Fix style mistakes (partial)" This reverts commit 48a033b87f4fdc1ce14ff86cc019e1c703cd2741. * Revert "Add blank lines under each line with `conn =`" This reverts commit 773a6d3beba2cf89eac75913078b40c4f5190dd4. * Revert "Get rid of repetitive `&mut *context.conn().await?`" This reverts commit d2c6263ea13710177d49b2791278db5ad115fca5. * Use DbConn for CaptchaAnswer methods * DbConn trait * Remove more `&mut *` * Fix stuff * Re-run CI * try to make ci start * fix * fix * Fix api_common::utils * Fix apub::activities::block * Fix apub::api::resolve_object * Fix some things * Revert "Fix some things" This reverts commit 2bf8574bc8333d8d34ca542d61a0a5b50039c24d. * Revert "Fix apub::api::resolve_object" This reverts commit 3e4059aabbe485b2ff060bdeced8ef958ff62832. * Revert "Fix apub::activities::block" This reverts commit 3b02389abd780a7b1b8a2c89e26febdaa6a12159. * Revert "Fix api_common::utils" This reverts commit 7dc73de613a5618fa57eb06450f3699bbcb41254. * Revert "Revert "Fix api_common::utils"" This reverts commit f740f115e5457e83e53cc223e48196a2c47a9975. * Revert "Revert "Fix apub::activities::block"" This reverts commit 2ee206af7c885c10092cf209bf4a5b1d60327866. * Revert "Revert "Fix apub::api::resolve_object"" This reverts commit 96ed8bf2e9dcadae760743929498312334e23d2e. * Fix fetch_local_site_data * Fix get_comment_parent_creator * Remove unused perma deleted text * Fix routes::feeds * Fix lib.rs * Update lib.rs * rerun ci * Attempt to create custom GetConn and RunQueryDsl traits * Start over * Add GetConn trait * aaaa * Revert "aaaa" This reverts commit acc9ca1aed10c39efdd91cefece066e035a1fe80. * Revert "Revert "aaaa"" This reverts commit 443a2a00a56d152bb7eb429efd0d29a78e21b163. * still aaaaaaaaaaaaa * Return to earlier thing Revert "Add GetConn trait" This reverts commit ab4e94aea5bd9d34cbcddf017339131047e75344. * Try to use DbPool enum * Revert "Try to use DbPool enum" This reverts commit e4d1712646a52006b865a1fbe0dcf79976fdb027. * DbConn and DbPool enums (db_schema only fails to compile for tests) * fmt * Make functions take `&mut DbPool<'_>` and make db_schema tests compile * Add try_join_with_pool macro and run fix-clippy on more crates * Fix some errors * I did it * Remove function variants that take connection * rerun ci * rerun ci * rerun ci
2023-07-11 13:09:59 +00:00
let community_id: Option<Url> = Community::read_from_name(&mut context.pool(), &name, false)
2022-11-09 10:05:00 +00:00
.await
.ok()
.map(|c| c.actor_id.into());
// Mastodon seems to prioritize the last webfinger item in case of duplicates. Put
// community last so that it gets prioritized. For Lemmy the order doesnt matter.
2021-11-16 17:03:09 +00:00
let links = vec![
webfinger_link_for_actor(user_id, "Person", &context),
webfinger_link_for_actor(community_id, "Group", &context),
2021-11-16 17:03:09 +00:00
]
.into_iter()
.flatten()
.collect();
2019-12-18 00:59:47 +00:00
let json = Webfinger {
subject: info.resource.clone(),
2021-11-16 17:03:09 +00:00
links,
..Default::default()
2021-11-16 17:03:09 +00:00
};
Ok(HttpResponse::Ok().json(json))
}
fn webfinger_link_for_actor(
url: Option<Url>,
kind: &str,
context: &LemmyContext,
) -> Vec<WebfingerLink> {
2021-11-16 17:03:09 +00:00
if let Some(url) = url {
let type_key = "https://www.w3.org/ns/activitystreams#type"
.parse()
.expect("parse url");
let mut vec = vec![
WebfingerLink {
rel: Some("http://webfinger.net/rel/profile-page".into()),
kind: Some("text/html".into()),
href: Some(url.clone()),
..Default::default()
},
WebfingerLink {
rel: Some("self".into()),
kind: Some("application/activity+json".into()),
2021-11-16 17:03:09 +00:00
href: Some(url),
properties: HashMap::from([(type_key, kind.into())]),
..Default::default()
2021-11-16 17:03:09 +00:00
},
];
// insert remote follow link
if kind == "Person" {
let template = format!(
"{}/activitypub/externalInteraction?uri={{uri}}",
context.settings().get_protocol_and_hostname()
);
vec.push(WebfingerLink {
rel: Some("http://ostatus.org/schema/1.0/subscribe".into()),
template: Some(template),
..Default::default()
});
}
vec
2021-11-16 17:03:09 +00:00
} else {
vec![]
}
2019-12-18 00:59:47 +00:00
}