Prefer Group actor when doing webfinger query on Lemmy server

This commit is contained in:
silverpill 2023-02-24 13:12:10 +00:00
parent f66e0b812f
commit f5c012769f
6 changed files with 38 additions and 9 deletions

View file

@ -15,12 +15,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Deprecated ### Deprecated
- Deprecated `proxy_url` configuration paramter (replaced by `federation.proxy_url`). - Deprecated `proxy_url` configuration parameter (replaced by `federation.proxy_url`).
### Fixed ### Fixed
- Prevent `delete-extraneous-posts` command from removing locally-linked posts. - Prevent `delete-extraneous-posts` command from removing locally-linked posts.
- Make webfinger response compatible with GNU Social account lookup. - Make webfinger response compatible with GNU Social account lookup.
- Prefer `Group` actor when doing webfinger query on Lemmy server.
## [1.14.0] - 2023-02-22 ## [1.14.0] - 2023-02-22

View file

@ -12,9 +12,10 @@ use mitra_utils::{
use crate::activitypub::{ use crate::activitypub::{
actors::types::Actor, actors::types::Actor,
constants::AP_MEDIA_TYPE, constants::{AP_CONTEXT, AP_MEDIA_TYPE},
identifiers::{local_actor_key_id, local_instance_actor_id}, identifiers::{local_actor_key_id, local_instance_actor_id},
types::Object, types::Object,
vocabulary::GROUP,
}; };
use crate::http_signatures::create::{ use crate::http_signatures::create::{
create_http_signature, create_http_signature,
@ -183,11 +184,28 @@ pub async fn perform_webfinger_query(
.error_for_status()? .error_for_status()?
.text().await?; .text().await?;
let jrd: JsonResourceDescriptor = serde_json::from_str(&webfinger_data)?; let jrd: JsonResourceDescriptor = serde_json::from_str(&webfinger_data)?;
let link = jrd.links.into_iter() // Lemmy servers can have Group and Person actors with the same name
.find(|link| link.rel == "self") // https://github.com/LemmyNet/lemmy/issues/2037
.ok_or(FetchError::OtherError("self link not found"))?; let ap_type_property = format!("{}#type", AP_CONTEXT);
let actor_url = link.href let group_link = jrd.links.iter()
.ok_or(FetchError::OtherError("account href not found"))?; .find(|link| {
link.rel == "self" &&
link.properties
.get(&ap_type_property)
.map(|val| val.as_str()) == Some(GROUP)
});
let link = if let Some(link) = group_link {
// Prefer Group if the actor type is provided
link
} else {
// Otherwise take first "self" link
jrd.links.iter()
.find(|link| link.rel == "self")
.ok_or(FetchError::OtherError("self link not found"))?
};
let actor_url = link.href.as_ref()
.ok_or(FetchError::OtherError("account href not found"))?
.to_string();
Ok(actor_url) Ok(actor_url)
} }

View file

@ -18,6 +18,7 @@ pub const UNDO: &str = "Undo";
pub const UPDATE: &str = "Update"; pub const UPDATE: &str = "Update";
// Actor types // Actor types
pub const GROUP: &str = "Group";
pub const PERSON: &str = "Person"; pub const PERSON: &str = "Person";
pub const SERVICE: &str = "Service"; pub const SERVICE: &str = "Service";

View file

@ -22,6 +22,7 @@ pub async fn get_nodeinfo(
rel: "http://nodeinfo.diaspora.software/ns/schema/2.0".to_string(), rel: "http://nodeinfo.diaspora.software/ns/schema/2.0".to_string(),
media_type: None, media_type: None,
href: Some(nodeinfo_2_0_url), href: Some(nodeinfo_2_0_url),
properties: Default::default(),
}; };
let jrd = JsonResourceDescriptor { let jrd = JsonResourceDescriptor {
subject: config.instance_url(), subject: config.instance_url(),

View file

@ -1,6 +1,9 @@
/// https://webfinger.net/ /// https://webfinger.net/
use std::fmt; use std::{
use std::str::FromStr; collections::HashMap,
fmt,
str::FromStr,
};
use regex::Regex; use regex::Regex;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
@ -63,6 +66,9 @@ pub struct Link {
pub media_type: Option<String>, pub media_type: Option<String>,
pub href: Option<String>, pub href: Option<String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub properties: HashMap<String, String>,
} }
// https://datatracker.ietf.org/doc/html/rfc7033#section-4.4 // https://datatracker.ietf.org/doc/html/rfc7033#section-4.4

View file

@ -62,11 +62,13 @@ async fn get_jrd(
rel: "http://webfinger.net/rel/profile-page".to_string(), rel: "http://webfinger.net/rel/profile-page".to_string(),
media_type: Some("text/html".to_string()), media_type: Some("text/html".to_string()),
href: Some(actor_id.clone()), href: Some(actor_id.clone()),
properties: Default::default(),
}; };
let link_actor = Link { let link_actor = Link {
rel: "self".to_string(), rel: "self".to_string(),
media_type: Some(AP_MEDIA_TYPE.to_string()), media_type: Some(AP_MEDIA_TYPE.to_string()),
href: Some(actor_id), href: Some(actor_id),
properties: Default::default(),
}; };
let jrd = JsonResourceDescriptor { let jrd = JsonResourceDescriptor {
subject: format!("acct:{}", actor_address), subject: format!("acct:{}", actor_address),