nodeinfo_controller.ex 5.06 KB
Newer Older
1
# Pleroma: A lightweight social networking server
kaniini's avatar
kaniini committed
2
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 4
# SPDX-License-Identifier: AGPL-3.0-only

dashie's avatar
dashie committed
5 6 7
defmodule Pleroma.Web.Nodeinfo.NodeinfoController do
  use Pleroma.Web, :controller

Haelwenn's avatar
Haelwenn committed
8
  alias Pleroma.Config
dashie's avatar
dashie committed
9
  alias Pleroma.Stats
Haelwenn's avatar
Haelwenn committed
10
  alias Pleroma.User
dashie's avatar
dashie committed
11
  alias Pleroma.Web
12
  alias Pleroma.Web.ActivityPub.MRF
13
  alias Pleroma.Web.Federator.Publisher
dashie's avatar
dashie committed
14 15 16 17

  def schemas(conn, _params) do
    response = %{
      links: [
luna's avatar
luna committed
18 19 20 21
        %{
          rel: "http://nodeinfo.diaspora.software/ns/schema/2.0",
          href: Web.base_url() <> "/nodeinfo/2.0.json"
        },
dashie's avatar
dashie committed
22
        %{
luna's avatar
luna committed
23 24
          rel: "http://nodeinfo.diaspora.software/ns/schema/2.1",
          href: Web.base_url() <> "/nodeinfo/2.1.json"
dashie's avatar
dashie committed
25 26 27 28 29 30 31
        }
      ]
    }

    json(conn, response)
  end

luna's avatar
luna committed
32 33
  # returns a nodeinfo 2.0 map, since 2.1 just adds a repository field
  # under software.
Haelwenn's avatar
Haelwenn committed
34
  def raw_nodeinfo do
35
    stats = Stats.get_stats()
36

minibikini's avatar
minibikini committed
37
    quarantined = Config.get([:instance, :quarantined_instances], [])
38

39
    staff_accounts =
Eugenij's avatar
Eugenij committed
40
      User.all_superusers()
41 42
      |> Enum.map(fn u -> u.ap_id end)

43
    federation_response =
minibikini's avatar
minibikini committed
44
      if Config.get([:instance, :mrf_transparency]) do
45 46 47 48
        {:ok, data} = MRF.describe()

        data
        |> Map.merge(%{quarantined_instances: quarantined})
href's avatar
href committed
49
        |> Map.put(:enabled, Config.get([:instance, :federating]))
50 51 52 53
      else
        %{}
      end

54 55 56 57 58
    features =
      [
        "pleroma_api",
        "mastodon_api",
        "mastodon_api_streaming",
kaniini's avatar
kaniini committed
59
        "polls",
60
        "pleroma_explicit_addressing",
61
        "shareable_emoji_packs",
62
        "multifetch",
minibikini's avatar
minibikini committed
63
        if Config.get([:media_proxy, :enabled]) do
64 65
          "media_proxy"
        end,
minibikini's avatar
minibikini committed
66
        if Config.get([:gopher, :enabled]) do
67 68
          "gopher"
        end,
minibikini's avatar
minibikini committed
69
        if Config.get([:chat, :enabled]) do
70 71
          "chat"
        end,
minibikini's avatar
minibikini committed
72
        if Config.get([:instance, :allow_relay]) do
73
          "relay"
74
        end,
minibikini's avatar
minibikini committed
75
        if Config.get([:instance, :safe_dm_mentions]) do
76
          "safe_dm_mentions"
77 78 79
        end
      ]
      |> Enum.filter(& &1)
80

luna's avatar
luna committed
81 82
    %{
      version: "2.0",
dashie's avatar
dashie committed
83
      software: %{
luna's avatar
luna committed
84 85
        name: Pleroma.Application.name() |> String.downcase(),
        version: Pleroma.Application.version()
dashie's avatar
dashie committed
86
      },
87
      protocols: Publisher.gather_nodeinfo_protocol_names(),
dashie's avatar
dashie committed
88 89 90 91
      services: %{
        inbound: [],
        outbound: []
      },
minibikini's avatar
minibikini committed
92
      openRegistrations: Config.get([:instance, :registrations_open]),
dashie's avatar
dashie committed
93 94
      usage: %{
        users: %{
95
          total: stats.user_count || 0
96
        },
97
        localPosts: stats.status_count || 0
dashie's avatar
dashie committed
98
      },
dashie's avatar
dashie committed
99
      metadata: %{
minibikini's avatar
minibikini committed
100 101 102
        nodeName: Config.get([:instance, :name]),
        nodeDescription: Config.get([:instance, :description]),
        private: !Config.get([:instance, :public], true),
Hakaba Hitoyo's avatar
Hakaba Hitoyo committed
103
        suggestions: %{
104
          enabled: false
105
        },
106
        staffAccounts: staff_accounts,
107
        federation: federation_response,
kaniini's avatar
kaniini committed
108
        pollLimits: Config.get([:instance, :poll_limits]),
minibikini's avatar
minibikini committed
109
        postFormats: Config.get([:instance, :allowed_post_formats]),
110
        uploadLimits: %{
minibikini's avatar
minibikini committed
111 112 113 114
          general: Config.get([:instance, :upload_limit]),
          avatar: Config.get([:instance, :avatar_upload_limit]),
          banner: Config.get([:instance, :banner_upload_limit]),
          background: Config.get([:instance, :background_upload_limit])
115
        },
116 117 118 119 120 121
        fieldsLimits: %{
          maxFields: Config.get([:instance, :max_account_fields]),
          maxRemoteFields: Config.get([:instance, :max_remote_account_fields]),
          nameLength: Config.get([:instance, :account_field_name_length]),
          valueLength: Config.get([:instance, :account_field_value_length])
        },
minibikini's avatar
minibikini committed
122 123
        accountActivationRequired: Config.get([:instance, :account_activation_required], false),
        invitesEnabled: Config.get([:instance, :invites_enabled], false),
124
        mailerEnabled: Config.get([Pleroma.Emails.Mailer, :enabled], false),
lain's avatar
lain committed
125
        features: features,
126 127
        restrictedNicknames: Config.get([Pleroma.User, :restricted_nicknames]),
        skipThreadContainment: Config.get([:instance, :skip_thread_containment], false)
dashie's avatar
dashie committed
128
      }
dashie's avatar
dashie committed
129
    }
luna's avatar
luna committed
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
  end

  # Schema definition: https://github.com/jhass/nodeinfo/blob/master/schemas/2.0/schema.json
  # and https://github.com/jhass/nodeinfo/blob/master/schemas/2.1/schema.json
  def nodeinfo(conn, %{"version" => "2.0"}) do
    conn
    |> put_resp_header(
      "content-type",
      "application/json; profile=http://nodeinfo.diaspora.software/ns/schema/2.0#; charset=utf-8"
    )
    |> json(raw_nodeinfo())
  end

  def nodeinfo(conn, %{"version" => "2.1"}) do
    raw_response = raw_nodeinfo()

    updated_software =
      raw_response
      |> Map.get(:software)
      |> Map.put(:repository, Pleroma.Application.repository())

151 152 153 154
    response =
      raw_response
      |> Map.put(:software, updated_software)
      |> Map.put(:version, "2.1")
dashie's avatar
dashie committed
155

156 157 158
    conn
    |> put_resp_header(
      "content-type",
luna's avatar
luna committed
159
      "application/json; profile=http://nodeinfo.diaspora.software/ns/schema/2.1#; charset=utf-8"
160 161
    )
    |> json(response)
dashie's avatar
dashie committed
162 163 164
  end

  def nodeinfo(conn, _) do
165
    render_error(conn, :not_found, "Nodeinfo schema version not handled")
dashie's avatar
dashie committed
166 167
  end
end