Merge branch 'streamer-refactoring' into 'develop'
[akkoma] / lib / pleroma / web / admin_api / admin_api_controller.ex
index 048ac80198320cee630adf7b1c73f4fa4f7e322b..544b9d7d8b530018120c3f1a9f15af36a223e43a 100644 (file)
@@ -5,6 +5,7 @@
 defmodule Pleroma.Web.AdminAPI.AdminAPIController do
   use Pleroma.Web, :controller
   alias Pleroma.Activity
+  alias Pleroma.ModerationLog
   alias Pleroma.User
   alias Pleroma.UserInviteToken
   alias Pleroma.Web.ActivityPub.ActivityPub
@@ -12,6 +13,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
   alias Pleroma.Web.AdminAPI.AccountView
   alias Pleroma.Web.AdminAPI.Config
   alias Pleroma.Web.AdminAPI.ConfigView
+  alias Pleroma.Web.AdminAPI.ModerationLogView
   alias Pleroma.Web.AdminAPI.ReportView
   alias Pleroma.Web.AdminAPI.Search
   alias Pleroma.Web.CommonAPI
@@ -25,35 +27,61 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
 
   action_fallback(:errors)
 
-  def user_delete(conn, %{"nickname" => nickname}) do
-    User.get_cached_by_nickname(nickname)
-    |> User.delete()
+  def user_delete(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
+    user = User.get_cached_by_nickname(nickname)
+    User.delete(user)
+
+    ModerationLog.insert_log(%{
+      actor: admin,
+      subject: user,
+      action: "delete"
+    })
 
     conn
     |> json(nickname)
   end
 
-  def user_follow(conn, %{"follower" => follower_nick, "followed" => followed_nick}) do
+  def user_follow(%{assigns: %{user: admin}} = conn, %{
+        "follower" => follower_nick,
+        "followed" => followed_nick
+      }) do
     with %User{} = follower <- User.get_cached_by_nickname(follower_nick),
          %User{} = followed <- User.get_cached_by_nickname(followed_nick) do
       User.follow(follower, followed)
+
+      ModerationLog.insert_log(%{
+        actor: admin,
+        followed: followed,
+        follower: follower,
+        action: "follow"
+      })
     end
 
     conn
     |> json("ok")
   end
 
-  def user_unfollow(conn, %{"follower" => follower_nick, "followed" => followed_nick}) do
+  def user_unfollow(%{assigns: %{user: admin}} = conn, %{
+        "follower" => follower_nick,
+        "followed" => followed_nick
+      }) do
     with %User{} = follower <- User.get_cached_by_nickname(follower_nick),
          %User{} = followed <- User.get_cached_by_nickname(followed_nick) do
       User.unfollow(follower, followed)
+
+      ModerationLog.insert_log(%{
+        actor: admin,
+        followed: followed,
+        follower: follower,
+        action: "unfollow"
+      })
     end
 
     conn
     |> json("ok")
   end
 
-  def users_create(conn, %{"users" => users}) do
+  def users_create(%{assigns: %{user: admin}} = conn, %{"users" => users}) do
     changesets =
       Enum.map(users, fn %{"nickname" => nickname, "email" => email, "password" => password} ->
         user_data = %{
@@ -78,10 +106,17 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
           |> Map.values()
           |> Enum.map(fn user ->
             {:ok, user} = User.post_register_action(user)
+
             user
           end)
           |> Enum.map(&AccountView.render("created.json", %{user: &1}))
 
+        ModerationLog.insert_log(%{
+          actor: admin,
+          subjects: Map.values(users),
+          action: "create"
+        })
+
         conn
         |> json(res)
 
@@ -129,23 +164,47 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
     end
   end
 
-  def user_toggle_activation(conn, %{"nickname" => nickname}) do
+  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.info.deactivated)
 
+    action = if user.info.deactivated, do: "activate", else: "deactivate"
+
+    ModerationLog.insert_log(%{
+      actor: admin,
+      subject: user,
+      action: action
+    })
+
     conn
     |> json(AccountView.render("show.json", %{user: updated_user}))
   end
 
-  def tag_users(conn, %{"nicknames" => nicknames, "tags" => tags}) do
-    with {:ok, _} <- User.tag(nicknames, tags),
-         do: json_response(conn, :no_content, "")
+  def tag_users(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames, "tags" => tags}) do
+    with {:ok, _} <- User.tag(nicknames, tags) do
+      ModerationLog.insert_log(%{
+        actor: admin,
+        nicknames: nicknames,
+        tags: tags,
+        action: "tag"
+      })
+
+      json_response(conn, :no_content, "")
+    end
   end
 
-  def untag_users(conn, %{"nicknames" => nicknames, "tags" => tags}) do
-    with {:ok, _} <- User.untag(nicknames, tags),
-         do: json_response(conn, :no_content, "")
+  def untag_users(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames, "tags" => tags}) do
+    with {:ok, _} <- User.untag(nicknames, tags) do
+      ModerationLog.insert_log(%{
+        actor: admin,
+        nicknames: nicknames,
+        tags: tags,
+        action: "untag"
+      })
+
+      json_response(conn, :no_content, "")
+    end
   end
 
   def list_users(conn, params) do
@@ -186,7 +245,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
     |> Enum.into(%{}, &{&1, true})
   end
 
-  def right_add(conn, %{"permission_group" => permission_group, "nickname" => nickname})
+  def right_add(%{assigns: %{user: admin}} = conn, %{
+        "permission_group" => permission_group,
+        "nickname" => nickname
+      })
       when permission_group in ["moderator", "admin"] do
     user = User.get_cached_by_nickname(nickname)
 
@@ -201,6 +263,13 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
       |> Ecto.Changeset.change()
       |> Ecto.Changeset.put_embed(:info, info_cng)
 
+    ModerationLog.insert_log(%{
+      action: "grant",
+      actor: admin,
+      subject: user,
+      permission: permission_group
+    })
+
     {:ok, _user} = User.update_and_set_cache(cng)
 
     json(conn, info)
@@ -221,7 +290,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
   end
 
   def right_delete(
-        %{assigns: %{user: %User{:nickname => admin_nickname}}} = conn,
+        %{assigns: %{user: %User{:nickname => admin_nickname} = admin}} = conn,
         %{
           "permission_group" => permission_group,
           "nickname" => nickname
@@ -245,6 +314,13 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
 
       {:ok, _user} = User.update_and_set_cache(cng)
 
+      ModerationLog.insert_log(%{
+        action: "revoke",
+        actor: admin,
+        subject: user,
+        permission: permission_group
+      })
+
       json(conn, info)
     end
   end
@@ -253,15 +329,33 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
     render_error(conn, :not_found, "No such permission_group")
   end
 
-  def set_activation_status(conn, %{"nickname" => nickname, "status" => status}) do
+  def set_activation_status(%{assigns: %{user: admin}} = conn, %{
+        "nickname" => nickname,
+        "status" => status
+      }) do
     with {:ok, status} <- Ecto.Type.cast(:boolean, status),
          %User{} = user <- User.get_cached_by_nickname(nickname),
-         {:ok, _} <- User.deactivate(user, !status),
-         do: json_response(conn, :no_content, "")
+         {:ok, _} <- User.deactivate(user, !status) do
+      action = if(user.info.deactivated, do: "activate", else: "deactivate")
+
+      ModerationLog.insert_log(%{
+        actor: admin,
+        subject: user,
+        action: action
+      })
+
+      json_response(conn, :no_content, "")
+    end
   end
 
-  def relay_follow(conn, %{"relay_url" => target}) do
+  def relay_follow(%{assigns: %{user: admin}} = conn, %{"relay_url" => target}) do
     with {:ok, _message} <- Relay.follow(target) do
+      ModerationLog.insert_log(%{
+        action: "relay_follow",
+        actor: admin,
+        target: target
+      })
+
       json(conn, target)
     else
       _ ->
@@ -271,8 +365,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
     end
   end
 
-  def relay_unfollow(conn, %{"relay_url" => target}) do
+  def relay_unfollow(%{assigns: %{user: admin}} = conn, %{"relay_url" => target}) do
     with {:ok, _message} <- Relay.unfollow(target) do
+      ModerationLog.insert_log(%{
+        action: "relay_unfollow",
+        actor: admin,
+        target: target
+      })
+
       json(conn, target)
     else
       _ ->
@@ -363,8 +463,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
     end
   end
 
-  def report_update_state(conn, %{"id" => id, "state" => state}) do
+  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
+      })
+
       conn
       |> put_view(ReportView)
       |> render("show.json", %{report: report})
@@ -381,6 +487,13 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
 
       {:ok, activity} = CommonAPI.post(user, params)
 
+      ModerationLog.insert_log(%{
+        action: "report_response",
+        actor: user,
+        subject: activity,
+        text: params["status"]
+      })
+
       conn
       |> put_view(StatusView)
       |> render("status.json", %{activity: activity})
@@ -393,8 +506,18 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
     end
   end
 
-  def status_update(conn, %{"id" => id} = params) do
+  def status_update(%{assigns: %{user: admin}} = conn, %{"id" => id} = params) do
     with {:ok, activity} <- CommonAPI.update_activity_scope(id, params) do
+      {:ok, sensitive} = Ecto.Type.cast(:boolean, params["sensitive"])
+
+      ModerationLog.insert_log(%{
+        action: "status_update",
+        actor: admin,
+        subject: activity,
+        sensitive: sensitive,
+        visibility: params["visibility"]
+      })
+
       conn
       |> put_view(StatusView)
       |> render("status.json", %{activity: activity})
@@ -403,10 +526,26 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
 
   def status_delete(%{assigns: %{user: user}} = conn, %{"id" => id}) do
     with {:ok, %Activity{}} <- CommonAPI.delete(id, user) do
+      ModerationLog.insert_log(%{
+        action: "status_delete",
+        actor: user,
+        subject_id: id
+      })
+
       json(conn, %{})
     end
   end
 
+  def list_log(conn, params) do
+    {page, page_size} = page_params(params)
+
+    log = ModerationLog.get_all(page, page_size)
+
+    conn
+    |> put_view(ModerationLogView)
+    |> render("index.json", %{log: log})
+  end
+
   def migrate_to_db(conn, _params) do
     Mix.Tasks.Pleroma.Config.run(["migrate_to_db"])
     json(conn, %{})