Implement NodeInfo 2.1
This commit is contained in:
parent
0817177282
commit
94a5f3a3cd
4 changed files with 117 additions and 31 deletions
|
@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Added `emojis` field to Mastodon API Account entity.
|
||||
- Support audio attachments.
|
||||
- Added CLI command for viewing unreachable actors.
|
||||
- Implemented NodeInfo 2.1.
|
||||
|
||||
### Changed
|
||||
|
||||
|
|
|
@ -169,8 +169,9 @@ async fn main() -> std::io::Result<()> {
|
|||
.service(activitypub::emoji_view)
|
||||
.service(activitypub::tag_view)
|
||||
.service(atom_scope())
|
||||
.service(nodeinfo::get_nodeinfo)
|
||||
.service(nodeinfo::get_nodeinfo_jrd)
|
||||
.service(nodeinfo::get_nodeinfo_2_0)
|
||||
.service(nodeinfo::get_nodeinfo_2_1)
|
||||
.service(web_client::profile_page_redirect())
|
||||
.service(web_client::post_page_redirect())
|
||||
.service(
|
||||
|
|
|
@ -4,16 +4,56 @@ use serde::Serialize;
|
|||
|
||||
use mitra_config::{Config, RegistrationType, MITRA_VERSION};
|
||||
|
||||
const MITRA_NAME: &str = "mitra";
|
||||
const MITRA_REPOSITORY: &str = "https://codeberg.org/silverpill/mitra";
|
||||
const ATOM_SERVICE: &str = "atom1.0";
|
||||
const ACTIVITYPUB_PROTOCOL: &str = "activitypub";
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Software {
|
||||
struct Software20 {
|
||||
name: String,
|
||||
version: String,
|
||||
}
|
||||
|
||||
impl Default for Software20 {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: MITRA_NAME.to_string(),
|
||||
version: MITRA_VERSION.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Software21 {
|
||||
name: String,
|
||||
version: String,
|
||||
repository: String,
|
||||
}
|
||||
|
||||
impl Default for Software21 {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: MITRA_NAME.to_string(),
|
||||
version: MITRA_VERSION.to_string(),
|
||||
repository: MITRA_REPOSITORY.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Services {
|
||||
inbound: Vec<String>,
|
||||
outbound: Vec<String>,
|
||||
inbound: Vec<&'static str>,
|
||||
outbound: Vec<&'static str>,
|
||||
}
|
||||
|
||||
impl Default for Services {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
inbound: vec![],
|
||||
outbound: vec![ATOM_SERVICE],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
|
@ -35,12 +75,25 @@ struct Metadata {
|
|||
node_description: String,
|
||||
}
|
||||
|
||||
impl Metadata {
|
||||
fn new(config: &Config) -> Self {
|
||||
Self {
|
||||
node_name: config.instance_title.clone(),
|
||||
node_description: config.instance_short_description.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn has_open_registrations(config: &Config) -> bool {
|
||||
config.registration.registration_type != RegistrationType::Invite
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct NodeInfo20 {
|
||||
version: String,
|
||||
software: Software,
|
||||
protocols: Vec<String>,
|
||||
version: &'static str,
|
||||
software: Software20,
|
||||
protocols: Vec<&'static str>,
|
||||
services: Services,
|
||||
open_registrations: bool,
|
||||
usage: Usage,
|
||||
|
@ -49,28 +102,40 @@ pub struct NodeInfo20 {
|
|||
|
||||
impl NodeInfo20 {
|
||||
pub fn new(config: &Config, usage: Usage) -> Self {
|
||||
let software = Software {
|
||||
name: "mitra".to_string(),
|
||||
version: MITRA_VERSION.to_string(),
|
||||
};
|
||||
let services = Services {
|
||||
inbound: vec![],
|
||||
outbound: vec!["atom1.0".to_string()],
|
||||
};
|
||||
let metadata = Metadata {
|
||||
node_name: config.instance_title.clone(),
|
||||
node_description: config.instance_short_description.clone(),
|
||||
};
|
||||
Self {
|
||||
version: "2.0".to_string(),
|
||||
software,
|
||||
protocols: vec!["activitypub".to_string()],
|
||||
services,
|
||||
open_registrations:
|
||||
config.registration.registration_type !=
|
||||
RegistrationType::Invite,
|
||||
version: "2.0",
|
||||
software: Software20::default(),
|
||||
protocols: vec![ACTIVITYPUB_PROTOCOL],
|
||||
services: Services::default(),
|
||||
open_registrations: has_open_registrations(config),
|
||||
usage,
|
||||
metadata,
|
||||
metadata: Metadata::new(config),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct NodeInfo21 {
|
||||
version: &'static str,
|
||||
software: Software21,
|
||||
protocols: Vec<&'static str>,
|
||||
services: Services,
|
||||
open_registrations: bool,
|
||||
usage: Usage,
|
||||
metadata: Metadata,
|
||||
}
|
||||
|
||||
impl NodeInfo21 {
|
||||
pub fn new(config: &Config, usage: Usage) -> Self {
|
||||
Self {
|
||||
version: "2.1",
|
||||
software: Software21::default(),
|
||||
protocols: vec![ACTIVITYPUB_PROTOCOL],
|
||||
services: Services::default(),
|
||||
open_registrations: has_open_registrations(config),
|
||||
usage,
|
||||
metadata: Metadata::new(config),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,22 +11,29 @@ use crate::webfinger::types::{
|
|||
JsonResourceDescriptor,
|
||||
};
|
||||
use super::helpers::get_usage;
|
||||
use super::types::NodeInfo20;
|
||||
use super::types::{NodeInfo20, NodeInfo21};
|
||||
|
||||
#[get("/.well-known/nodeinfo")]
|
||||
pub async fn get_nodeinfo(
|
||||
pub async fn get_nodeinfo_jrd(
|
||||
config: web::Data<Config>,
|
||||
) -> Result<HttpResponse, HttpError> {
|
||||
let nodeinfo_2_0_url = format!("{}/nodeinfo/2.0", config.instance_url());
|
||||
let link = Link {
|
||||
let nodeinfo_2_0_link = Link {
|
||||
rel: "http://nodeinfo.diaspora.software/ns/schema/2.0".to_string(),
|
||||
media_type: None,
|
||||
href: Some(nodeinfo_2_0_url),
|
||||
properties: Default::default(),
|
||||
};
|
||||
let nodeinfo_2_1_url = format!("{}/nodeinfo/2.1", config.instance_url());
|
||||
let nodeinfo_2_1_link = Link {
|
||||
rel: "http://nodeinfo.diaspora.software/ns/schema/2.1".to_string(),
|
||||
media_type: None,
|
||||
href: Some(nodeinfo_2_1_url),
|
||||
properties: Default::default(),
|
||||
};
|
||||
let jrd = JsonResourceDescriptor {
|
||||
subject: config.instance_url(),
|
||||
links: vec![link],
|
||||
links: vec![nodeinfo_2_0_link, nodeinfo_2_1_link],
|
||||
};
|
||||
let response = HttpResponse::Ok().json(jrd);
|
||||
Ok(response)
|
||||
|
@ -43,3 +50,15 @@ pub async fn get_nodeinfo_2_0(
|
|||
let response = HttpResponse::Ok().json(nodeinfo);
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
#[get("/nodeinfo/2.1")]
|
||||
pub async fn get_nodeinfo_2_1(
|
||||
config: web::Data<Config>,
|
||||
db_pool: web::Data<DbPool>,
|
||||
) -> Result<HttpResponse, HttpError> {
|
||||
let db_client = &**get_database_client(&db_pool).await?;
|
||||
let usage = get_usage(db_client).await?;
|
||||
let nodeinfo = NodeInfo21::new(&config, usage);
|
||||
let response = HttpResponse::Ok().json(nodeinfo);
|
||||
Ok(response)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue