Fork of Pleroma with site-specific changes and feature branches https://git.pleroma.social/pleroma/pleroma
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

151 行
4.4KB

  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Web.AdminAPI.ConfigController do
  5. use Pleroma.Web, :controller
  6. alias Pleroma.Config
  7. alias Pleroma.ConfigDB
  8. alias Pleroma.Web.Plugs.OAuthScopesPlug
  9. plug(Pleroma.Web.ApiSpec.CastAndValidate)
  10. plug(OAuthScopesPlug, %{scopes: ["write"], admin: true} when action == :update)
  11. plug(
  12. OAuthScopesPlug,
  13. %{scopes: ["read"], admin: true}
  14. when action in [:show, :descriptions]
  15. )
  16. action_fallback(Pleroma.Web.AdminAPI.FallbackController)
  17. defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.Admin.ConfigOperation
  18. def descriptions(conn, _params) do
  19. descriptions = Enum.filter(Pleroma.Docs.JSON.compiled_descriptions(), &whitelisted_config?/1)
  20. json(conn, descriptions)
  21. end
  22. def show(conn, %{only_db: true}) do
  23. with :ok <- configurable_from_database() do
  24. configs = Pleroma.Repo.all(ConfigDB)
  25. render(conn, "index.json", %{
  26. configs: configs,
  27. need_reboot: Restarter.Pleroma.need_reboot?()
  28. })
  29. end
  30. end
  31. def show(conn, _params) do
  32. with :ok <- configurable_from_database() do
  33. configs = ConfigDB.get_all_as_keyword()
  34. merged =
  35. Config.Holder.default_config()
  36. |> ConfigDB.merge(configs)
  37. |> Enum.map(fn {group, values} ->
  38. Enum.map(values, fn {key, value} ->
  39. db =
  40. if configs[group][key] do
  41. ConfigDB.get_db_keys(configs[group][key], key)
  42. end
  43. db_value = configs[group][key]
  44. merged_value =
  45. if not is_nil(db_value) and Keyword.keyword?(db_value) and
  46. ConfigDB.sub_key_full_update?(group, key, Keyword.keys(db_value)) do
  47. ConfigDB.merge_group(group, key, value, db_value)
  48. else
  49. value
  50. end
  51. %ConfigDB{
  52. group: group,
  53. key: key,
  54. value: merged_value
  55. }
  56. |> Pleroma.Maps.put_if_present(:db, db)
  57. end)
  58. end)
  59. |> List.flatten()
  60. render(conn, "index.json", %{
  61. configs: merged,
  62. need_reboot: Restarter.Pleroma.need_reboot?()
  63. })
  64. end
  65. end
  66. def update(%{body_params: %{configs: configs}} = conn, _) do
  67. with :ok <- configurable_from_database() do
  68. results =
  69. configs
  70. |> Enum.filter(&whitelisted_config?/1)
  71. |> Enum.map(fn
  72. %{group: group, key: key, delete: true} = params ->
  73. ConfigDB.delete(%{group: group, key: key, subkeys: params[:subkeys]})
  74. %{group: group, key: key, value: value} ->
  75. ConfigDB.update_or_create(%{group: group, key: key, value: value})
  76. end)
  77. |> Enum.reject(fn {result, _} -> result == :error end)
  78. {deleted, updated} =
  79. results
  80. |> Enum.map(fn {:ok, %{key: key, value: value} = config} ->
  81. Map.put(config, :db, ConfigDB.get_db_keys(value, key))
  82. end)
  83. |> Enum.split_with(&(Ecto.get_meta(&1, :state) == :deleted))
  84. Config.TransferTask.load_and_update_env(deleted, false)
  85. if not Restarter.Pleroma.need_reboot?() do
  86. changed_reboot_settings? =
  87. (updated ++ deleted)
  88. |> Enum.any?(&Config.TransferTask.pleroma_need_restart?(&1.group, &1.key, &1.value))
  89. if changed_reboot_settings?, do: Restarter.Pleroma.need_reboot()
  90. end
  91. render(conn, "index.json", %{
  92. configs: updated,
  93. need_reboot: Restarter.Pleroma.need_reboot?()
  94. })
  95. end
  96. end
  97. defp configurable_from_database do
  98. if Config.get(:configurable_from_database) do
  99. :ok
  100. else
  101. {:error, "To use this endpoint you need to enable configuration from database."}
  102. end
  103. end
  104. defp whitelisted_config?(group, key) do
  105. if whitelisted_configs = Config.get(:database_config_whitelist) do
  106. Enum.any?(whitelisted_configs, fn
  107. {whitelisted_group} ->
  108. group == inspect(whitelisted_group)
  109. {whitelisted_group, whitelisted_key} ->
  110. group == inspect(whitelisted_group) && key == inspect(whitelisted_key)
  111. end)
  112. else
  113. true
  114. end
  115. end
  116. defp whitelisted_config?(%{group: group, key: key}) do
  117. whitelisted_config?(group, key)
  118. end
  119. defp whitelisted_config?(%{group: group} = config) do
  120. whitelisted_config?(group, config[:key])
  121. end
  122. end