Merge branch 'develop' into feature/reports-groups-and-multiple-state-update
[akkoma] / lib / pleroma / web / admin_api / admin_api_controller.ex
index d825a5d281dd45d559cd4d16a3357d026b3216ab..1f48ce8c17efd3cf120874b40e108b3675b00f6c 100644 (file)
@@ -11,6 +11,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
   alias Pleroma.UserInviteToken
   alias Pleroma.Web.ActivityPub.ActivityPub
   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
@@ -46,11 +47,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
            :user_delete,
            :users_create,
            :user_toggle_activation,
+           :user_activate,
+           :user_deactivate,
            :tag_users,
            :untag_users,
            :right_add,
-           :right_delete,
-           :set_activation_status
+           :right_delete
          ]
   )
 
@@ -98,7 +100,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
 
     ModerationLog.insert_log(%{
       actor: admin,
-      subject: user,
+      subject: [user],
       action: "delete"
     })
 
@@ -106,6 +108,20 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
     |> json(nickname)
   end
 
+  def user_delete(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
+    users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
+    User.delete(users)
+
+    ModerationLog.insert_log(%{
+      actor: admin,
+      subject: users,
+      action: "delete"
+    })
+
+    conn
+    |> json(nicknames)
+  end
+
   def user_follow(%{assigns: %{user: admin}} = conn, %{
         "follower" => follower_nick,
         "followed" => followed_nick
@@ -231,6 +247,24 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
     end
   end
 
+  def user_toggle_activation(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
+    user = User.get_cached_by_nickname(nickname)
+
+    {:ok, updated_user} = User.deactivate(user, !user.deactivated)
+
+    action = if user.deactivated, do: "activate", else: "deactivate"
+
+    ModerationLog.insert_log(%{
+      actor: admin,
+      subject: [user],
+      action: action
+    })
+
+    conn
+    |> put_view(AccountView)
+    |> render("show.json", %{user: updated_user})
+  end
+
   def user_activate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
     users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
     {:ok, updated_users} = User.deactivate(users, false)
@@ -301,6 +335,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
     }
 
     with {:ok, users, count} <- Search.user(Map.merge(search_params, filters)),
+         {:ok, users, count} <- filter_relay_user(users, count),
          do:
            conn
            |> json(
@@ -312,6 +347,17 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
            )
   end
 
+  defp filter_relay_user(users, count) do
+    filtered_users = Enum.reject(users, &relay_user?/1)
+    count = if Enum.any?(users, &relay_user?/1), do: length(filtered_users), else: count
+
+    {:ok, filtered_users, count}
+  end
+
+  defp relay_user?(user) do
+    user.ap_id == Relay.relay_ap_id()
+  end
+
   @filters ~w(local external active deactivated is_admin is_moderator)
 
   @spec maybe_parse_filters(String.t()) :: %{required(String.t()) => true} | %{}
@@ -325,16 +371,16 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
     |> Enum.into(%{}, &{&1, true})
   end
 
-  def right_add(%{assigns: %{user: admin}} = conn, %{
+  def right_add_multiple(%{assigns: %{user: admin}} = conn, %{
         "permission_group" => permission_group,
         "nicknames" => nicknames
       })
       when permission_group in ["moderator", "admin"] do
-    info = Map.put(%{}, "is_" <> permission_group, true)
+    update = %{:"is_#{permission_group}" => true}
 
     users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
 
-    User.update_info(users, &User.Info.admin_api_update(&1, info))
+    for u <- users, do: User.admin_api_update(u, update)
 
     ModerationLog.insert_log(%{
       action: "grant",
@@ -343,7 +389,33 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
       permission: permission_group
     })
 
-    json(conn, info)
+    json(conn, update)
+  end
+
+  def right_add_multiple(conn, _) do
+    render_error(conn, :not_found, "No such permission_group")
+  end
+
+  def right_add(%{assigns: %{user: admin}} = conn, %{
+        "permission_group" => permission_group,
+        "nickname" => nickname
+      })
+      when permission_group in ["moderator", "admin"] do
+    fields = %{:"is_#{permission_group}" => true}
+
+    {:ok, user} =
+      nickname
+      |> User.get_cached_by_nickname()
+      |> User.admin_api_update(fields)
+
+    ModerationLog.insert_log(%{
+      action: "grant",
+      actor: admin,
+      subject: [user],
+      permission: permission_group
+    })
+
+    json(conn, fields)
   end
 
   def right_add(conn, _) do
@@ -355,12 +427,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
 
     conn
     |> json(%{
-      is_moderator: user.info.is_moderator,
-      is_admin: user.info.is_admin
+      is_moderator: user.is_moderator,
+      is_admin: user.is_admin
     })
   end
 
-  def right_delete(
+  def right_delete_multiple(
         %{assigns: %{user: %{nickname: admin_nickname} = admin}} = conn,
         %{
           "permission_group" => permission_group,
@@ -369,11 +441,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
       )
       when permission_group in ["moderator", "admin"] do
     with false <- Enum.member?(nicknames, admin_nickname) do
-      info = Map.put(%{}, "is_" <> permission_group, false)
+      update = %{:"is_#{permission_group}" => false}
 
       users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
 
-      User.update_info(users, &User.Info.admin_api_update(&1, info))
+      for u <- users, do: User.admin_api_update(u, update)
 
       ModerationLog.insert_log(%{
         action: "revoke",
@@ -382,16 +454,55 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
         permission: permission_group
       })
 
-      json(conn, info)
+      json(conn, update)
     else
       _ -> render_error(conn, :forbidden, "You can't revoke your own admin/moderator status.")
     end
   end
 
-  def right_delete(conn, _) do
+  def right_delete_multiple(conn, _) do
     render_error(conn, :not_found, "No such permission_group")
   end
 
+  def right_delete(
+        %{assigns: %{user: admin}} = conn,
+        %{
+          "permission_group" => permission_group,
+          "nickname" => nickname
+        }
+      )
+      when permission_group in ["moderator", "admin"] do
+    fields = %{:"is_#{permission_group}" => false}
+
+    {:ok, user} =
+      nickname
+      |> User.get_cached_by_nickname()
+      |> User.admin_api_update(fields)
+
+    ModerationLog.insert_log(%{
+      action: "revoke",
+      actor: admin,
+      subject: [user],
+      permission: permission_group
+    })
+
+    json(conn, fields)
+  end
+
+  def right_delete(%{assigns: %{user: %{nickname: nickname}}} = conn, %{"nickname" => nickname}) do
+    render_error(conn, :forbidden, "You can't revoke your own admin status.")
+  end
+
+  def relay_list(conn, _params) do
+    with {:ok, list} <- Relay.list() do
+      json(conn, %{relays: list})
+    else
+      _ ->
+        conn
+        |> put_status(500)
+    end
+  end
+
   def relay_follow(%{assigns: %{user: admin}} = conn, %{"relay_url" => target}) do
     with {:ok, _message} <- Relay.follow(target) do
       ModerationLog.insert_log(%{
@@ -508,19 +619,15 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
   def list_reports(conn, params) do
     {page, page_size} = page_params(params)
 
-    params =
-      params
-      |> Map.put("type", "Flag")
-      |> Map.put("skip_preload", true)
-      |> Map.put("total", true)
-      |> Map.put("limit", page_size)
-      |> Map.put("offset", (page - 1) * page_size)
-
-    reports = ActivityPub.fetch_activities([], params, :offset)
+    conn
+    |> put_view(ReportView)
+    |> render("index.json", %{reports: Utils.get_reports(params, page, page_size)})
+  end
 
+  def list_grouped_reports(conn, _params) do
     conn
     |> put_view(ReportView)
-    |> render("index.json", %{reports: reports})
+    |> render("index_grouped.json", Utils.get_reports_grouped_by_status())
   end
 
   def report_show(conn, %{"id" => id}) do
@@ -533,17 +640,26 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
     end
   end
 
-  def report_update_state(%{assigns: %{user: admin}} = conn, %{"id" => id, "state" => state}) do
-    with {:ok, report} <- CommonAPI.update_report_state(id, state) do
-      ModerationLog.insert_log(%{
-        action: "report_update",
-        actor: admin,
-        subject: report
-      })
+  def reports_update(%{assigns: %{user: admin}} = conn, %{"reports" => reports}) do
+    result =
+      reports
+      |> Enum.map(fn report ->
+        with {:ok, activity} <- CommonAPI.update_report_state(report["id"], report["state"]) do
+          ModerationLog.insert_log(%{
+            action: "report_update",
+            actor: admin,
+            subject: activity
+          })
+
+          activity
+        else
+          {:error, message} -> %{id: report["id"], error: message}
+        end
+      end)
 
-      conn
-      |> put_view(ReportView)
-      |> render("show.json", Report.extract_report_info(report))
+    case Enum.any?(result, &Map.has_key?(&1, :error)) do
+      true -> json_response(conn, :bad_request, result)
+      false -> json_response(conn, :no_content, "")
     end
   end