Skip to content
This repository has been archived by the owner on Aug 2, 2020. It is now read-only.

Add node info endpoint #38

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions app/controllers/well_known/node_info_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

module WellKnown
class NodeInfoController < ActionController::Base
include RoutingHelper

before_action { response.headers['Vary'] = 'Accept' }

def index
render json: ActiveModelSerializers::SerializableResource.new({}, serializer: NodeDiscoverySerializer)
end

def show
render json: ActiveModelSerializers::SerializableResource.new({}, serializer: NodeInfoSerializer)
end
end
end
4 changes: 4 additions & 0 deletions app/presenters/instance_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ class InstancePresenter
to: Setting
)

def active_count(timespan: Time.zone.now - 1.month..Time.zone.now)
Status.select('distinct (account_id)').where(local: true, created_at: timespan).count
end

def contact_account
Account.find_local(Setting.site_contact_username.gsub(/\A@/, ''))
end
Expand Down
16 changes: 16 additions & 0 deletions app/serializers/node_discovery_serializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

class NodeDiscoverySerializer < ActiveModel::Serializer
include RoutingHelper

attributes :links

def links
[
{
rel: 'http://nodeinfo.diaspora.software/ns/schema/2.0',
href: node_info_schema_url('2.0'),
},
]
end
end
84 changes: 84 additions & 0 deletions app/serializers/node_info_serializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# frozen_string_literal: true

class NodeInfoSerializer < ActiveModel::Serializer
include RoutingHelper

attributes :version, :usage, :software, :services,
:protocols, :openRegistrations, :metaData

def version
'2.0'
end

def usage
{
users: {
total: instance_presenter.user_count,
activeHalfyear: instance_presenter.active_count(timespan: Time.zone.now - 6.months..Time.zone.now),
activeMonth: instance_presenter.active_count,
},
localPosts: instance_presenter.status_count,
}
end

def software
{
version: Mastodon::Version.to_s,
name: 'mastodon',
repository: Mastodon::Version.source_base_url,
}
end

def services
{
outbound: [],
inbound: [],
}
end

def protocols
%w(ostatus activitypub)
end

def openRegistrations
Setting.open_registrations
end

def metaData
{
nodeName: instance_presenter.site_title,
nodeDescription: instance_presenter.site_description,
nodeTerms: instance_presenter.site_terms,
siteContactEmail: instance_presenter.site_contact_email,
domain_count: instance_presenter.domain_count,
features: features,
invitesEnabled: Setting.min_invite_role != 'admin',
federation: federation,
}
end

def features
%w(mastodon_api mastodon_api_streaming)
end

def federation
domains = DomainBlock.all
feds = {
reject_media: [],
reject_reports: [],
}
domains.each do |domain|
feds[domain.severity] = [] unless feds.keys.include?(domain.severity)
feds[domain.severity] << domain.domain
feds[:reject_media] << domain.domain if domain.reject_media
feds[:reject_reports] << domain.domain if domain.reject_reports
end
feds
end

private

def instance_presenter
@instance_presenter ||= InstancePresenter.new
end
end
4 changes: 3 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
tokens: 'oauth/tokens'
end

get '.well-known/host-meta', to: 'well_known/host_meta#show', as: :host_meta, defaults: { format: 'xml' }
get '.well-known/host-meta', to: 'well_known/host_meta#show', as: :host_meta, defaults: { format: 'xml' }
get '.well-known/nodeinfo', to: 'well_known/node_info#index', as: :node_info, defaults: { format: 'json' }
get 'nodeinfo/:version_number', to: 'well_known/node_info#show', as: :node_info_schema, defaults: { format: 'json' }
get '.well-known/webfinger', to: 'well_known/webfinger#show', as: :webfinger
get '.well-known/change-password', to: redirect('/auth/edit')
get 'manifest', to: 'manifests#show', defaults: { format: 'json' }
Expand Down
38 changes: 38 additions & 0 deletions spec/controllers/well_known/node_info_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
require 'rails_helper'

describe WellKnown::NodeInfoController, type: :controller do
render_views

describe 'GET #index' do
it 'returns json document pointing to node info' do
get :index

json_response = JSON.parse(response.body)

expect(response).to have_http_status(200)
expect(response.content_type).to eq 'application/json'
expect(json_response.keys.include?('links')).to be true
expect(json_response['links'][0]['rel']).to eq 'http://nodeinfo.diaspora.software/ns/schema/2.0'
expect(json_response['links'][0]['href'].include?('nodeinfo/2.0')).to be true
end
end

describe 'GET #show' do
it 'returns json document pointing to node info' do
get :show, params: { version_number: 2 }

json_response = JSON.parse(response.body)

expect(response).to have_http_status(200)
expect(response.content_type).to eq 'application/json'
expect(json_response.keys.include?('version')).to be true
expect(json_response.keys.include?('usage')).to be true
expect(json_response.keys.include?('software')).to be true
expect(json_response.keys.include?('services')).to be true
expect(json_response.keys.include?('protocols')).to be true
expect(json_response.keys.include?('openRegistrations')).to be true
expect(json_response.keys.include?('usage')).to be true
expect(json_response.keys.include?('metaData')).to be true
end
end
end