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 `proxy_url` configuration paramter (replaced by `federation.proxy_url`).
- Deprecated `proxy_url` configuration parameter (replaced by `federation.proxy_url`).
### Fixed
- Prevent `delete-extraneous-posts` command from removing locally-linked posts.
- 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

View file

@ -12,9 +12,10 @@ use mitra_utils::{
use crate::activitypub::{
actors::types::Actor,
constants::AP_MEDIA_TYPE,
constants::{AP_CONTEXT, AP_MEDIA_TYPE},
identifiers::{local_actor_key_id, local_instance_actor_id},
types::Object,
vocabulary::GROUP,
};
use crate::http_signatures::create::{
create_http_signature,
@ -183,11 +184,28 @@ pub async fn perform_webfinger_query(
.error_for_status()?
.text().await?;
let jrd: JsonResourceDescriptor = serde_json::from_str(&webfinger_data)?;
let link = jrd.links.into_iter()
.find(|link| link.rel == "self")
.ok_or(FetchError::OtherError("self link not found"))?;
let actor_url = link.href
.ok_or(FetchError::OtherError("account href not found"))?;
// Lemmy servers can have Group and Person actors with the same name
// https://github.com/LemmyNet/lemmy/issues/2037
let ap_type_property = format!("{}#type", AP_CONTEXT);
let group_link = jrd.links.iter()
.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)
}

View file

@ -18,6 +18,7 @@ pub const UNDO: &str = "Undo";
pub const UPDATE: &str = "Update";
// Actor types
pub const GROUP: &str = "Group";
pub const PERSON: &str = "Person";
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(),
media_type: None,
href: Some(nodeinfo_2_0_url),
properties: Default::default(),
};
let jrd = JsonResourceDescriptor {
subject: config.instance_url(),

View file

@ -1,6 +1,9 @@
/// https://webfinger.net/
use std::fmt;
use std::str::FromStr;
use std::{
collections::HashMap,
fmt,
str::FromStr,
};
use regex::Regex;
use serde::{Serialize, Deserialize};
@ -63,6 +66,9 @@ pub struct Link {
pub media_type: 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

View file

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