logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://anongit.hacktivis.me/git/pleroma.git/

config_controller.ex (5655B)


  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2022 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, replace_params: false)
  10. plug(OAuthScopesPlug, %{scopes: ["admin:write"]} when action == :update)
  11. plug(
  12. OAuthScopesPlug,
  13. %{scopes: ["admin:read"]}
  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. defp translate_descriptions(descriptions, path \\ []) do
  19. Enum.map(descriptions, fn desc -> translate_item(desc, path) end)
  20. end
  21. defp translate_string(str, path, type) do
  22. Gettext.dpgettext(
  23. Pleroma.Web.Gettext,
  24. "config_descriptions",
  25. Pleroma.Docs.Translator.Compiler.msgctxt_for(path, type),
  26. str
  27. )
  28. end
  29. defp maybe_put_translated(item, key, path) do
  30. if item[key] do
  31. Map.put(
  32. item,
  33. key,
  34. translate_string(
  35. item[key],
  36. path ++ [Pleroma.Docs.Translator.Compiler.key_for(item)],
  37. to_string(key)
  38. )
  39. )
  40. else
  41. item
  42. end
  43. end
  44. defp translate_item(item, path) do
  45. item
  46. |> maybe_put_translated(:label, path)
  47. |> maybe_put_translated(:description, path)
  48. |> translate_children(path)
  49. end
  50. defp translate_children(%{children: children} = item, path) when is_list(children) do
  51. item
  52. |> Map.put(
  53. :children,
  54. translate_descriptions(children, path ++ [Pleroma.Docs.Translator.Compiler.key_for(item)])
  55. )
  56. end
  57. defp translate_children(item, _path) do
  58. item
  59. end
  60. def descriptions(conn, _params) do
  61. descriptions = Enum.filter(Pleroma.Docs.JSON.compiled_descriptions(), &whitelisted_config?/1)
  62. json(conn, translate_descriptions(descriptions))
  63. end
  64. def show(%{private: %{open_api_spex: %{params: %{only_db: true}}}} = conn, _) do
  65. with :ok <- :ok do
  66. configs = Pleroma.Repo.all(ConfigDB)
  67. render(conn, "index.json", %{
  68. configs: configs,
  69. need_reboot: Restarter.Pleroma.need_reboot?()
  70. })
  71. end
  72. end
  73. def show(conn, _params) do
  74. with :ok <- :ok do
  75. configs = ConfigDB.get_all_as_keyword()
  76. merged =
  77. Config.Holder.default_config()
  78. |> ConfigDB.merge(configs)
  79. |> Enum.map(fn {group, values} ->
  80. Enum.map(values, fn {key, value} ->
  81. db =
  82. if configs[group][key] do
  83. ConfigDB.get_db_keys(configs[group][key], key)
  84. end
  85. db_value = configs[group][key]
  86. merged_value =
  87. if not is_nil(db_value) and Keyword.keyword?(db_value) and
  88. ConfigDB.sub_key_full_update?(group, key, Keyword.keys(db_value)) do
  89. ConfigDB.merge_group(group, key, value, db_value)
  90. else
  91. value
  92. end
  93. %ConfigDB{
  94. group: group,
  95. key: key,
  96. value: merged_value
  97. }
  98. |> Pleroma.Maps.put_if_present(:db, db)
  99. end)
  100. end)
  101. |> List.flatten()
  102. render(conn, "index.json", %{
  103. configs: merged,
  104. need_reboot: Restarter.Pleroma.need_reboot?()
  105. })
  106. end
  107. end
  108. def update(%{private: %{open_api_spex: %{body_params: %{configs: configs}}}} = conn, _) do
  109. with :ok <- configurable_from_database() do
  110. results =
  111. configs
  112. |> Enum.filter(&whitelisted_config?/1)
  113. |> Enum.map(fn
  114. %{group: group, key: key, delete: true} = params ->
  115. ConfigDB.delete(%{group: group, key: key, subkeys: params[:subkeys]})
  116. %{group: group, key: key, value: value} ->
  117. ConfigDB.update_or_create(%{group: group, key: key, value: value})
  118. end)
  119. |> Enum.reject(fn {result, _} -> result == :error end)
  120. {deleted, updated} =
  121. results
  122. |> Enum.map(fn {:ok, %{key: key, value: value} = config} ->
  123. Map.put(config, :db, ConfigDB.get_db_keys(value, key))
  124. end)
  125. |> Enum.split_with(&(Ecto.get_meta(&1, :state) == :deleted))
  126. Config.TransferTask.load_and_update_env(deleted, false)
  127. if not Restarter.Pleroma.need_reboot?() do
  128. changed_reboot_settings? =
  129. (updated ++ deleted)
  130. |> Enum.any?(&Config.TransferTask.pleroma_need_restart?(&1.group, &1.key, &1.value))
  131. if changed_reboot_settings?, do: Restarter.Pleroma.need_reboot()
  132. end
  133. render(conn, "index.json", %{
  134. configs: updated,
  135. need_reboot: Restarter.Pleroma.need_reboot?()
  136. })
  137. end
  138. end
  139. defp configurable_from_database do
  140. if Config.get(:configurable_from_database) do
  141. :ok
  142. else
  143. {:error, "You must enable configurable_from_database in your config file."}
  144. end
  145. end
  146. defp whitelisted_config?(group, key) do
  147. if whitelisted_configs = Config.get(:database_config_whitelist) do
  148. Enum.any?(whitelisted_configs, fn
  149. {whitelisted_group} ->
  150. group == inspect(whitelisted_group)
  151. {whitelisted_group, whitelisted_key} ->
  152. group == inspect(whitelisted_group) && key == inspect(whitelisted_key)
  153. end)
  154. else
  155. true
  156. end
  157. end
  158. defp whitelisted_config?(%{group: group, key: key}) do
  159. whitelisted_config?(group, key)
  160. end
  161. defp whitelisted_config?(%{group: group} = config) do
  162. whitelisted_config?(group, config[:key])
  163. end
  164. end