Make nodeinfo standard compliant, upgrade to nodeinfo 2.1 (fixes #4702) (#4706)

* Always set activitypub protocol in nodeinfo response (fixes #4702)

* Add mandatory fields
This commit is contained in:
Nutomic 2024-05-14 04:53:20 +02:00 committed by GitHub
parent cb80980027
commit 8b6a4c060e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -43,21 +43,18 @@ async fn node_info(context: web::Data<LemmyContext>) -> Result<HttpResponse, Err
.map_err(|_| ErrorBadRequest(LemmyError::from(anyhow!("not_found"))))? .map_err(|_| ErrorBadRequest(LemmyError::from(anyhow!("not_found"))))?
.ok_or(ErrorBadRequest(LemmyError::from(anyhow!("not_found"))))?; .ok_or(ErrorBadRequest(LemmyError::from(anyhow!("not_found"))))?;
let protocols = if site_view.local_site.federation_enabled {
Some(vec!["activitypub".to_string()])
} else {
None
};
// Since there are 3 registration options, // Since there are 3 registration options,
// we need to set open_registrations as true if RegistrationMode is not Closed. // we need to set open_registrations as true if RegistrationMode is not Closed.
let open_registrations = Some(site_view.local_site.registration_mode != RegistrationMode::Closed); let open_registrations = Some(site_view.local_site.registration_mode != RegistrationMode::Closed);
let json = NodeInfo { let json = NodeInfo {
version: Some("2.0".to_string()), version: Some("2.1".to_string()),
software: Some(NodeInfoSoftware { software: Some(NodeInfoSoftware {
name: Some("lemmy".to_string()), name: Some("lemmy".to_string()),
version: Some(VERSION.to_string()), version: Some(VERSION.to_string()),
repository: Some("https://github.com/LemmyNet/lemmy".to_string()),
homepage: Some("https://join-lemmy.org/".to_string()),
}), }),
protocols, protocols: Some(vec!["activitypub".to_string()]),
usage: Some(NodeInfoUsage { usage: Some(NodeInfoUsage {
users: Some(NodeInfoUsers { users: Some(NodeInfoUsers {
total: Some(site_view.counts.users), total: Some(site_view.counts.users),
@ -68,6 +65,11 @@ async fn node_info(context: web::Data<LemmyContext>) -> Result<HttpResponse, Err
local_comments: Some(site_view.counts.comments), local_comments: Some(site_view.counts.comments),
}), }),
open_registrations, open_registrations,
services: Some(NodeInfoServices {
inbound: Some(vec![]),
outbound: Some(vec![]),
}),
metadata: Some(vec![]),
}; };
Ok(HttpResponse::Ok().json(json)) Ok(HttpResponse::Ok().json(json))
@ -84,6 +86,7 @@ struct NodeInfoWellKnownLinks {
pub href: Url, pub href: Url,
} }
/// Nodeinfo spec: http://nodeinfo.diaspora.software/docson/index.html#/ns/schema/2.1
#[derive(Serialize, Deserialize, Debug, Default)] #[derive(Serialize, Deserialize, Debug, Default)]
#[serde(rename_all = "camelCase", default)] #[serde(rename_all = "camelCase", default)]
pub struct NodeInfo { pub struct NodeInfo {
@ -92,6 +95,9 @@ pub struct NodeInfo {
pub protocols: Option<Vec<String>>, pub protocols: Option<Vec<String>>,
pub usage: Option<NodeInfoUsage>, pub usage: Option<NodeInfoUsage>,
pub open_registrations: Option<bool>, pub open_registrations: Option<bool>,
/// These fields are required by the spec for no reason
pub services: Option<NodeInfoServices>,
pub metadata: Option<Vec<String>>,
} }
#[derive(Serialize, Deserialize, Debug, Default)] #[derive(Serialize, Deserialize, Debug, Default)]
@ -99,6 +105,8 @@ pub struct NodeInfo {
pub struct NodeInfoSoftware { pub struct NodeInfoSoftware {
pub name: Option<String>, pub name: Option<String>,
pub version: Option<String>, pub version: Option<String>,
pub repository: Option<String>,
pub homepage: Option<String>,
} }
#[derive(Serialize, Deserialize, Debug, Default)] #[derive(Serialize, Deserialize, Debug, Default)]
@ -116,3 +124,10 @@ pub struct NodeInfoUsers {
pub active_halfyear: Option<i64>, pub active_halfyear: Option<i64>,
pub active_month: Option<i64>, pub active_month: Option<i64>,
} }
#[derive(Serialize, Deserialize, Debug, Default)]
#[serde(rename_all = "camelCase", default)]
pub struct NodeInfoServices {
pub inbound: Option<Vec<String>>,
pub outbound: Option<Vec<String>>,
}