Merge branch 'admin-be' into 'develop'
[akkoma] / lib / pleroma / web / admin_api / admin_api_controller.ex
index 23dcbedbacba8cead7068ae585dd4033de214f58..2314d32741fe0c42dbc6d979b364aa0dd103e5cd 100644 (file)
@@ -8,6 +8,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
   import Pleroma.Web.ControllerHelper, only: [json_response: 3]
 
   alias Pleroma.Activity
+  alias Pleroma.ConfigDB
   alias Pleroma.ModerationLog
   alias Pleroma.Plugs.OAuthScopesPlug
   alias Pleroma.ReportNote
@@ -17,7 +18,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
   alias Pleroma.Web.ActivityPub.Relay
   alias Pleroma.Web.ActivityPub.Utils
   alias Pleroma.Web.AdminAPI.AccountView
-  alias Pleroma.Web.AdminAPI.Config
   alias Pleroma.Web.AdminAPI.ConfigView
   alias Pleroma.Web.AdminAPI.ModerationLogView
   alias Pleroma.Web.AdminAPI.Report
@@ -36,19 +36,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
   plug(
     OAuthScopesPlug,
     %{scopes: ["read:accounts"], admin: true}
-    when action in [:list_users, :user_show, :right_get, :invites]
+    when action in [:list_users, :user_show, :right_get]
   )
 
   plug(
     OAuthScopesPlug,
     %{scopes: ["write:accounts"], admin: true}
     when action in [
-           :get_invite_token,
-           :revoke_invite,
-           :email_invite,
            :get_password_reset,
-           :user_follow,
-           :user_unfollow,
            :user_delete,
            :users_create,
            :user_toggle_activation,
@@ -61,6 +56,20 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
          ]
   )
 
+  plug(OAuthScopesPlug, %{scopes: ["read:invites"], admin: true} when action == :invites)
+
+  plug(
+    OAuthScopesPlug,
+    %{scopes: ["write:invites"], admin: true}
+    when action in [:create_invite_token, :revoke_invite, :email_invite]
+  )
+
+  plug(
+    OAuthScopesPlug,
+    %{scopes: ["write:follows"], admin: true}
+    when action in [:user_follow, :user_unfollow, :relay_follow, :relay_unfollow]
+  )
+
   plug(
     OAuthScopesPlug,
     %{scopes: ["read:reports"], admin: true}
@@ -70,7 +79,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
   plug(
     OAuthScopesPlug,
     %{scopes: ["write:reports"], admin: true}
-    when action in [:report_update_state, :report_respond]
+    when action in [:reports_update]
   )
 
   plug(
@@ -88,13 +97,13 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
   plug(
     OAuthScopesPlug,
     %{scopes: ["read"], admin: true}
-    when action in [:config_show, :migrate_to_db, :migrate_from_db, :list_log]
+    when action in [:config_show, :migrate_from_db, :list_log]
   )
 
   plug(
     OAuthScopesPlug,
     %{scopes: ["write"], admin: true}
-    when action in [:relay_follow, :relay_unfollow, :config_update]
+    when action == :config_update
   )
 
   action_fallback(:errors)
@@ -632,7 +641,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
   def force_password_reset(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
     users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
 
-    Enum.map(users, &User.force_password_reset_async/1)
+    Enum.each(users, &User.force_password_reset_async/1)
 
     ModerationLog.insert_log(%{
       actor: admin,
@@ -785,7 +794,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
   end
 
   def migrate_from_db(conn, _params) do
-    with :ok <- check_dynamic_configuration(conn) do
+    with :ok <- configurable_from_database(conn) do
       Mix.Tasks.Pleroma.Config.run([
         "migrate_from_db",
         "--env",
@@ -797,12 +806,15 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
     end
   end
 
-  def config_show(conn, _params) do
-    with :ok <- check_dynamic_configuration(conn) do
-      configs = Pleroma.Repo.all(Config)
+  def config_show(conn, %{"only_db" => true}) do
+    with :ok <- configurable_from_database(conn) do
+      configs = Pleroma.Repo.all(ConfigDB)
 
       if configs == [] do
-        errors(conn, {:error, "To use dynamic configuration migrate your settings to database."})
+        errors(
+          conn,
+          {:error, "To use configuration from database migrate your settings to database."}
+        )
       else
         conn
         |> put_view(ConfigView)
@@ -811,25 +823,74 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
     end
   end
 
+  def config_show(conn, _params) do
+    with :ok <- configurable_from_database(conn) do
+      configs = ConfigDB.get_all_as_keyword()
+
+      if configs == [] do
+        errors(
+          conn,
+          {:error, "To use configuration from database migrate your settings to database."}
+        )
+      else
+        merged =
+          Pleroma.Config.Holder.config()
+          |> ConfigDB.merge(configs)
+          |> Enum.map(fn {group, values} ->
+            Enum.map(values, fn {key, value} ->
+              db =
+                if configs[group][key] do
+                  ConfigDB.get_db_keys(configs[group][key], key)
+                end
+
+              db_value = configs[group][key]
+
+              merged_value =
+                if !is_nil(db_value) and Keyword.keyword?(db_value) and
+                     ConfigDB.sub_key_full_update?(group, key, Keyword.keys(db_value)) do
+                  ConfigDB.merge_group(group, key, value, db_value)
+                else
+                  value
+                end
+
+              setting = %{
+                group: ConfigDB.convert(group),
+                key: ConfigDB.convert(key),
+                value: ConfigDB.convert(merged_value)
+              }
+
+              if db, do: Map.put(setting, :db, db), else: setting
+            end)
+          end)
+          |> List.flatten()
+
+        json(conn, %{configs: merged})
+      end
+    end
+  end
+
   def config_update(conn, %{"configs" => configs}) do
-    with :ok <- check_dynamic_configuration(conn) do
-      updated =
+    with :ok <- configurable_from_database(conn) do
+      {_errors, results} =
         Enum.map(configs, fn
-          %{"group" => group, "key" => key, "delete" => "true"} = params ->
-            with {:ok, config} <-
-                   Config.delete(%{group: group, key: key, subkeys: params["subkeys"]}) do
-              config
-            end
+          %{"group" => group, "key" => key, "delete" => true} = params ->
+            ConfigDB.delete(%{group: group, key: key, subkeys: params["subkeys"]})
 
           %{"group" => group, "key" => key, "value" => value} ->
-            with {:ok, config} <-
-                   Config.update_or_create(%{group: group, key: key, value: value}) do
-              config
-            end
+            ConfigDB.update_or_create(%{group: group, key: key, value: value})
+        end)
+        |> Enum.split_with(fn result -> elem(result, 0) == :error end)
+
+      {deleted, updated} =
+        results
+        |> Enum.map(fn {:ok, config} ->
+          Map.put(config, :db, ConfigDB.get_db_keys(config))
+        end)
+        |> Enum.split_with(fn config ->
+          Ecto.get_meta(config, :state) == :deleted
         end)
-        |> Enum.reject(&is_nil(&1))
 
-      Pleroma.Config.TransferTask.load_and_update_env()
+      Pleroma.Config.TransferTask.load_and_update_env(deleted)
 
       Mix.Tasks.Pleroma.Config.run([
         "migrate_from_db",
@@ -843,11 +904,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
     end
   end
 
-  defp check_dynamic_configuration(conn) do
-    if Pleroma.Config.get([:instance, :dynamic_configuration]) do
+  defp configurable_from_database(conn) do
+    if Pleroma.Config.get(:configurable_from_database) do
       :ok
     else
-      errors(conn, {:error, "To use this endpoint you need to enable dynamic configuration."})
+      errors(
+        conn,
+        {:error, "To use this endpoint you need to enable configuration from database."}
+      )
     end
   end