From f20c1afe4681f589364c67c9968dc712fe0d9865 Mon Sep 17 00:00:00 2001 From: Alexander Strizhakov Date: Wed, 3 Mar 2021 08:48:02 +0300 Subject: [PATCH] config descriptions v2 endpoint with tabs field --- CHANGELOG.md | 4 ++ docs/development/API/admin_api.md | 42 +++++++++++++++ lib/pleroma/docs/json.ex | 8 ++- lib/pleroma/web/activity_pub/mrf.ex | 2 - .../web/admin_api/controllers/config_controller.ex | 23 +++++++- .../api_spec/operations/admin/config_operation.ex | 63 ++++++++++++++++------ lib/pleroma/web/router.ex | 5 ++ test/pleroma/web/activity_pub/mrf_test.exs | 1 - .../controllers/config_controller_test.exs | 20 ++++++- 9 files changed, 145 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed08701fd..bd57501c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - The `application` metadata returned with statuses is no longer hardcoded. Apps that want to display these details will now have valid data for new posts after this change. +### Added + +- Admin API: Added `GET /api/v2/pleroma/admin/config/descriptions` endpoint, differs from `/api/v1/pleroma/admin/config/descriptions` in response format and has additional field with the tabs list. + ## Unreleased (Patch) ## [2.3.0] - 2020-03-01 diff --git a/docs/development/API/admin_api.md b/docs/development/API/admin_api.md index 902403a40..45f470b2c 100644 --- a/docs/development/API/admin_api.md +++ b/docs/development/API/admin_api.md @@ -1107,6 +1107,7 @@ Loads json generated from `config/descriptions.exs`. "type": "group", // string or list with possible values, "description": "Upload general settings", // string "tab": "mrf", + "label": "MRF", "children": [ { "key": ":uploader", // string or module name `Pleroma.Upload` @@ -1126,6 +1127,47 @@ Loads json generated from `config/descriptions.exs`. }] ``` +## `GET /api/v2/pleroma/admin/config/descriptions` + +### Get tabs and config descriptions + +Loads json generated from `config/descriptions.exs`. + +- Params: none +- Response: + +```json +{ + "tabs": [{"tab": "activity_pub", "label": "ActivityPub"}], + "descriptions": [ + { + "group": ":pleroma", // string + "key": "ModuleName", // string + "type": "group", // string or list with possible values, + "description": "Upload general settings", // string + "tab": "mrf", + "label": "MRF", + "children": [ + { + "key": ":uploader", // string or module name `Pleroma.Upload` + "type": "module", + "description": "Module which will be used for uploads", + "suggestions": ["module1", "module2"] + }, + { + "key": ":filters", + "type": ["list", "module"], + "description": "List of filter modules for uploads", + "suggestions": [ + "module1", "module2", "module3" + ] + } + ] + } + ] +} +``` + ## `GET /api/v1/pleroma/admin/moderation_log` ### Get moderation log diff --git a/lib/pleroma/docs/json.ex b/lib/pleroma/docs/json.ex index f22432ea4..d28659b91 100644 --- a/lib/pleroma/docs/json.ex +++ b/lib/pleroma/docs/json.ex @@ -7,7 +7,9 @@ defmodule Pleroma.Docs.JSON do @external_resource "config/description.exs" @raw_config Pleroma.Config.Loader.read("config/description.exs") @raw_descriptions @raw_config[:pleroma][:config_description] + @raw_tabs @raw_config[:pleroma][:tabs] @term __MODULE__.Compiled + @tabs __MODULE__.CompiledTabs @spec compile :: :ok def compile do @@ -16,13 +18,17 @@ defmodule Pleroma.Docs.JSON do |> Enum.reduce(@raw_descriptions, fn description, acc -> [description | acc] end) :persistent_term.put(@term, Pleroma.Docs.Generator.convert_to_strings(descriptions)) + :persistent_term.put(@tabs, @raw_tabs) end - @spec compiled_descriptions :: Map.t() + @spec compiled_descriptions :: [map()] def compiled_descriptions do :persistent_term.get(@term) end + @spec compiled_tabs() :: [map()] + def compiled_tabs, do: :persistent_term.get(@tabs) + @spec process(keyword()) :: {:ok, String.t()} def process(descriptions) do with path <- "docs/generated_config.json", diff --git a/lib/pleroma/web/activity_pub/mrf.ex b/lib/pleroma/web/activity_pub/mrf.ex index d1ae1845f..ef5a09a93 100644 --- a/lib/pleroma/web/activity_pub/mrf.ex +++ b/lib/pleroma/web/activity_pub/mrf.ex @@ -12,7 +12,6 @@ defmodule Pleroma.Web.ActivityPub.MRF do group: :pleroma, key: :mrf, tab: :mrf, - tab_label: "MRF", label: "MRF", type: :group, description: "General MRF settings", @@ -154,7 +153,6 @@ defmodule Pleroma.Web.ActivityPub.MRF do |> Map.merge(policy.config_description) |> Map.put(:group, :pleroma) |> Map.put(:tab, :mrf) - |> Map.put(:tab_label, "MRF") |> Map.put(:type, :group) if Enum.all?(@required_description_keys, &Map.has_key?(description, &1)) do diff --git a/lib/pleroma/web/admin_api/controllers/config_controller.ex b/lib/pleroma/web/admin_api/controllers/config_controller.ex index a718d7b8d..1042662c7 100644 --- a/lib/pleroma/web/admin_api/controllers/config_controller.ex +++ b/lib/pleroma/web/admin_api/controllers/config_controller.ex @@ -15,19 +15,34 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do plug( OAuthScopesPlug, %{scopes: ["admin:read"]} - when action in [:show, :descriptions] + when action in [:show, :descriptions, :descriptions2] ) action_fallback(Pleroma.Web.AdminAPI.FallbackController) defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.Admin.ConfigOperation + @doc """ + GET /api/v1/pleroma/admin/config/descriptions + """ def descriptions(conn, _params) do - descriptions = Enum.filter(Pleroma.Docs.JSON.compiled_descriptions(), &whitelisted_config?/1) + descriptions = + whitelisted_descriptions() + |> Enum.map(&Map.delete(&1, "tab")) json(conn, descriptions) end + @doc """ + GET /api/v2/pleroma/admin/config/descriptions + """ + def descriptions2(conn, _params) do + json(conn, %{ + tabs: Pleroma.Docs.JSON.compiled_tabs(), + descriptions: whitelisted_descriptions() + }) + end + def show(conn, %{only_db: true}) do with :ok <- configurable_from_database() do configs = Pleroma.Repo.all(ConfigDB) @@ -126,6 +141,10 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do end end + defp whitelisted_descriptions do + Enum.filter(Pleroma.Docs.JSON.compiled_descriptions(), &whitelisted_config?/1) + end + defp whitelisted_config?(group, key) do if whitelisted_configs = Config.get(:database_config_whitelist) do Enum.any?(whitelisted_configs, fn diff --git a/lib/pleroma/web/api_spec/operations/admin/config_operation.ex b/lib/pleroma/web/api_spec/operations/admin/config_operation.ex index 30c3433b7..0ad8937c8 100644 --- a/lib/pleroma/web/api_spec/operations/admin/config_operation.ex +++ b/lib/pleroma/web/api_spec/operations/admin/config_operation.ex @@ -78,31 +78,64 @@ defmodule Pleroma.Web.ApiSpec.Admin.ConfigOperation do parameters: admin_api_params(), responses: %{ 200 => + Operation.response("Config Descriptions", "application/json", descriptions_schema()), + 400 => Operation.response("Bad Request", "application/json", ApiError) + } + } + end + + def descriptions2_operation do + %Operation{ + tags: ["Instance configuration"], + summary: "Retrieve config description", + operationId: "AdminAPI.ConfigController.descriptions2", + security: [%{"oAuth" => ["admin:read"]}], + parameters: admin_api_params(), + responses: %{ + 200 => Operation.response("Config Descriptions", "application/json", %Schema{ + type: :object, + properties: %{ + tabs: %Schema{ + type: :array, + items: %Schema{ + type: :object, + properties: %{tab: %Schema{type: :string}, label: %Schema{type: :string}} + } + }, + descriptions: descriptions_schema() + } + }), + 400 => Operation.response("Bad Request", "application/json", ApiError) + } + } + end + + defp descriptions_schema do + %Schema{ + type: :array, + items: %Schema{ + type: :object, + properties: %{ + group: %Schema{type: :string}, + key: %Schema{type: :string}, + tab: %Schema{type: :string}, + label: %Schema{type: :string}, + type: %Schema{oneOf: [%Schema{type: :string}, %Schema{type: :array}]}, + description: %Schema{type: :string}, + children: %Schema{ type: :array, items: %Schema{ type: :object, properties: %{ - group: %Schema{type: :string}, key: %Schema{type: :string}, type: %Schema{oneOf: [%Schema{type: :string}, %Schema{type: :array}]}, description: %Schema{type: :string}, - children: %Schema{ - type: :array, - items: %Schema{ - type: :object, - properties: %{ - key: %Schema{type: :string}, - type: %Schema{oneOf: [%Schema{type: :string}, %Schema{type: :array}]}, - description: %Schema{type: :string}, - suggestions: %Schema{type: :array} - } - } - } + suggestions: %Schema{type: :array} } } - }), - 400 => Operation.response("Bad Request", "application/json", ApiError) + } + } } } end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 72ad14f05..a96e8f67c 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -155,6 +155,11 @@ defmodule Pleroma.Web.Router do post("/uploader_callback/:upload_path", UploaderController, :callback) end + scope "/api/v2/pleroma/admin", Pleroma.Web.AdminAPI do + pipe_through(:admin_api) + get("/config/descriptions", ConfigController, :descriptions2) + end + scope "/api/v1/pleroma/admin", Pleroma.Web.AdminAPI do pipe_through(:admin_api) diff --git a/test/pleroma/web/activity_pub/mrf_test.exs b/test/pleroma/web/activity_pub/mrf_test.exs index afd51a3d8..7c1eef7e0 100644 --- a/test/pleroma/web/activity_pub/mrf_test.exs +++ b/test/pleroma/web/activity_pub/mrf_test.exs @@ -100,7 +100,6 @@ defmodule Pleroma.Web.ActivityPub.MRFTest do description: "Some description", group: :pleroma, tab: :mrf, - tab_label: "MRF", type: :group } end diff --git a/test/pleroma/web/admin_api/controllers/config_controller_test.exs b/test/pleroma/web/admin_api/controllers/config_controller_test.exs index 578a4c914..10cc85fd3 100644 --- a/test/pleroma/web/admin_api/controllers/config_controller_test.exs +++ b/test/pleroma/web/admin_api/controllers/config_controller_test.exs @@ -1412,8 +1412,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do end end - describe "GET /api/pleroma/admin/config/descriptions" do - test "structure", %{conn: conn} do + describe "config descriptions" do + test "api v1 structure", %{conn: conn} do conn = get(conn, "/api/pleroma/admin/config/descriptions") assert [child | _others] = json_response_and_validate_schema(conn, 200) @@ -1424,6 +1424,22 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do assert child["description"] end + test "api v2 structure", %{conn: conn} do + conn = get(conn, "/api/v2/pleroma/admin/config/descriptions") + + assert %{"tabs" => tabs, "descriptions" => [child | _others]} = + json_response_and_validate_schema(conn, 200) + + assert Enum.all?(tabs, fn tab -> + Map.has_key?(tab, "tab") and Map.has_key?(tab, "label") + end) + + assert child["children"] + assert child["key"] + assert String.starts_with?(child["group"], ":") + assert child["description"] + end + test "filters by database configuration whitelist", %{conn: conn} do clear_config(:database_config_whitelist, [ {:pleroma, :instance},