diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pleroma/moderation_log.ex | 64 | ||||
-rw-r--r-- | lib/pleroma/user.ex | 20 | ||||
-rw-r--r-- | lib/pleroma/web/admin_api/admin_api_controller.ex | 134 | ||||
-rw-r--r-- | lib/pleroma/web/admin_api/views/account_view.ex | 6 | ||||
-rw-r--r-- | lib/pleroma/web/router.ex | 11 |
5 files changed, 174 insertions, 61 deletions
diff --git a/lib/pleroma/moderation_log.ex b/lib/pleroma/moderation_log.ex index 352cad433..e8884e6e8 100644 --- a/lib/pleroma/moderation_log.ex +++ b/lib/pleroma/moderation_log.ex @@ -86,18 +86,18 @@ defmodule Pleroma.ModerationLog do parsed_datetime end - @spec insert_log(%{actor: User, subject: User, action: String.t(), permission: String.t()}) :: + @spec insert_log(%{actor: User, subject: [User], action: String.t(), permission: String.t()}) :: {:ok, ModerationLog} | {:error, any} def insert_log(%{ actor: %User{} = actor, - subject: %User{} = subject, + subject: subjects, action: action, permission: permission }) do %ModerationLog{ data: %{ "actor" => user_to_map(actor), - "subject" => user_to_map(subject), + "subject" => user_to_map(subjects), "action" => action, "permission" => permission, "message" => "" @@ -303,13 +303,16 @@ defmodule Pleroma.ModerationLog do end @spec insert_log_entry_with_message(ModerationLog) :: {:ok, ModerationLog} | {:error, any} - defp insert_log_entry_with_message(entry) do entry.data["message"] |> put_in(get_log_entry_message(entry)) |> Repo.insert() end + defp user_to_map(users) when is_list(users) do + users |> Enum.map(&user_to_map/1) + end + defp user_to_map(%User{} = user) do user |> Map.from_struct() @@ -349,10 +352,10 @@ defmodule Pleroma.ModerationLog do data: %{ "actor" => %{"nickname" => actor_nickname}, "action" => "delete", - "subject" => %{"nickname" => subject_nickname, "type" => "user"} + "subject" => subjects } }) do - "@#{actor_nickname} deleted user @#{subject_nickname}" + "@#{actor_nickname} deleted users: #{users_to_nicknames_string(subjects)}" end @spec get_log_entry_message(ModerationLog) :: String.t() @@ -363,12 +366,7 @@ defmodule Pleroma.ModerationLog do "subjects" => subjects } }) do - nicknames = - subjects - |> Enum.map(&"@#{&1["nickname"]}") - |> Enum.join(", ") - - "@#{actor_nickname} created users: #{nicknames}" + "@#{actor_nickname} created users: #{users_to_nicknames_string(subjects)}" end @spec get_log_entry_message(ModerationLog) :: String.t() @@ -376,10 +374,10 @@ defmodule Pleroma.ModerationLog do data: %{ "actor" => %{"nickname" => actor_nickname}, "action" => "activate", - "subject" => %{"nickname" => subject_nickname, "type" => "user"} + "subject" => users } }) do - "@#{actor_nickname} activated user @#{subject_nickname}" + "@#{actor_nickname} activated users: #{users_to_nicknames_string(users)}" end @spec get_log_entry_message(ModerationLog) :: String.t() @@ -387,10 +385,10 @@ defmodule Pleroma.ModerationLog do data: %{ "actor" => %{"nickname" => actor_nickname}, "action" => "deactivate", - "subject" => %{"nickname" => subject_nickname, "type" => "user"} + "subject" => users } }) do - "@#{actor_nickname} deactivated user @#{subject_nickname}" + "@#{actor_nickname} deactivated users: #{users_to_nicknames_string(users)}" end @spec get_log_entry_message(ModerationLog) :: String.t() @@ -402,14 +400,9 @@ defmodule Pleroma.ModerationLog do "action" => "tag" } }) do - nicknames_string = - nicknames - |> Enum.map(&"@#{&1}") - |> Enum.join(", ") - tags_string = tags |> Enum.join(", ") - "@#{actor_nickname} added tags: #{tags_string} to users: #{nicknames_string}" + "@#{actor_nickname} added tags: #{tags_string} to users: #{nicknames_to_string(nicknames)}" end @spec get_log_entry_message(ModerationLog) :: String.t() @@ -421,14 +414,9 @@ defmodule Pleroma.ModerationLog do "action" => "untag" } }) do - nicknames_string = - nicknames - |> Enum.map(&"@#{&1}") - |> Enum.join(", ") - tags_string = tags |> Enum.join(", ") - "@#{actor_nickname} removed tags: #{tags_string} from users: #{nicknames_string}" + "@#{actor_nickname} removed tags: #{tags_string} from users: #{nicknames_to_string(nicknames)}" end @spec get_log_entry_message(ModerationLog) :: String.t() @@ -436,11 +424,11 @@ defmodule Pleroma.ModerationLog do data: %{ "actor" => %{"nickname" => actor_nickname}, "action" => "grant", - "subject" => %{"nickname" => subject_nickname}, + "subject" => users, "permission" => permission } }) do - "@#{actor_nickname} made @#{subject_nickname} #{permission}" + "@#{actor_nickname} made #{users_to_nicknames_string(users)} #{permission}" end @spec get_log_entry_message(ModerationLog) :: String.t() @@ -448,11 +436,11 @@ defmodule Pleroma.ModerationLog do data: %{ "actor" => %{"nickname" => actor_nickname}, "action" => "revoke", - "subject" => %{"nickname" => subject_nickname}, + "subject" => users, "permission" => permission } }) do - "@#{actor_nickname} revoked #{permission} role from @#{subject_nickname}" + "@#{actor_nickname} revoked #{permission} role from #{users_to_nicknames_string(users)}" end @spec get_log_entry_message(ModerationLog) :: String.t() @@ -551,4 +539,16 @@ defmodule Pleroma.ModerationLog do }) do "@#{actor_nickname} deleted status ##{subject_id}" end + + defp nicknames_to_string(nicknames) do + nicknames + |> Enum.map(&"@#{&1}") + |> Enum.join(", ") + end + + defp users_to_nicknames_string(users) do + users + |> Enum.map(&"@#{&1["nickname"]}") + |> Enum.join(", ") + end end diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 1e055014e..917bcf2ef 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1061,7 +1061,15 @@ defmodule Pleroma.User do BackgroundWorker.enqueue("deactivate_user", %{"user_id" => user.id, "status" => status}) end - def deactivate(%User{} = user, status \\ true) do + def deactivate(user, status \\ true) + + def deactivate(users, status) when is_list(users) do + Repo.transaction(fn -> + for user <- users, do: deactivate(user, status) + end) + end + + def deactivate(%User{} = user, status) do with {:ok, user} <- update_info(user, &User.Info.set_activation_status(&1, status)) do Enum.each(get_followers(user), &invalidate_cache/1) Enum.each(get_friends(user), &update_follower_count/1) @@ -1074,6 +1082,10 @@ defmodule Pleroma.User do update_info(user, &User.Info.update_notification_settings(&1, settings)) end + def delete(users) when is_list(users) do + for user <- users, do: delete(user) + end + def delete(%User{} = user) do BackgroundWorker.enqueue("delete_user", %{"user_id" => user.id}) end @@ -1627,6 +1639,12 @@ defmodule Pleroma.User do `fun` is called with the `user.info`. """ + def update_info(users, fun) when is_list(users) do + Repo.transaction(fn -> + for user <- users, do: update_info(user, fun) + end) + end + def update_info(user, fun) do user |> change_info(fun) diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/admin_api_controller.ex index 513bae800..ab0d0fe0a 100644 --- a/lib/pleroma/web/admin_api/admin_api_controller.ex +++ b/lib/pleroma/web/admin_api/admin_api_controller.ex @@ -46,6 +46,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do :user_delete, :users_create, :user_toggle_activation, + :user_activate, + :user_deactivate, :tag_users, :untag_users, :right_add, @@ -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 @@ -240,7 +256,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do ModerationLog.insert_log(%{ actor: admin, - subject: user, + subject: [user], action: action }) @@ -249,6 +265,36 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do |> 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) + + ModerationLog.insert_log(%{ + actor: admin, + subject: users, + action: "activate" + }) + + conn + |> put_view(AccountView) + |> render("index.json", %{users: Keyword.values(updated_users)}) + end + + def user_deactivate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do + users = Enum.map(nicknames, &User.get_cached_by_nickname/1) + {:ok, updated_users} = User.deactivate(users, true) + + ModerationLog.insert_log(%{ + actor: admin, + subject: users, + action: "deactivate" + }) + + conn + |> put_view(AccountView) + |> render("index.json", %{users: Keyword.values(updated_users)}) + end + def tag_users(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames, "tags" => tags}) do with {:ok, _} <- User.tag(nicknames, tags) do ModerationLog.insert_log(%{ @@ -313,6 +359,31 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do |> Enum.into(%{}, &{&1, true}) end + 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) + + users = nicknames |> Enum.map(&User.get_cached_by_nickname/1) + + User.update_info(users, &User.Info.admin_api_update(&1, info)) + + ModerationLog.insert_log(%{ + action: "grant", + actor: admin, + subject: users, + permission: permission_group + }) + + json(conn, info) + 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 @@ -328,7 +399,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do ModerationLog.insert_log(%{ action: "grant", actor: admin, - subject: user, + subject: [user], permission: permission_group }) @@ -349,8 +420,36 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do }) end - def right_delete(%{assigns: %{user: %{nickname: nickname}}} = conn, %{"nickname" => nickname}) do - render_error(conn, :forbidden, "You can't revoke your own admin status.") + def right_delete_multiple( + %{assigns: %{user: %{nickname: admin_nickname} = admin}} = conn, + %{ + "permission_group" => permission_group, + "nicknames" => nicknames + } + ) + when permission_group in ["moderator", "admin"] do + with false <- Enum.member?(nicknames, admin_nickname) do + info = Map.put(%{}, "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)) + + ModerationLog.insert_log(%{ + action: "revoke", + actor: admin, + subject: users, + permission: permission_group + }) + + json(conn, info) + else + _ -> render_error(conn, :forbidden, "You can't revoke your own admin/moderator status.") + end + end + + def right_delete_multiple(conn, _) do + render_error(conn, :not_found, "No such permission_group") end def right_delete( @@ -371,34 +470,15 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do ModerationLog.insert_log(%{ action: "revoke", actor: admin, - subject: user, + subject: [user], permission: permission_group }) json(conn, info) end - def right_delete(conn, _) do - render_error(conn, :not_found, "No such permission_group") - end - - 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 - action = if(user.info.deactivated, do: "activate", else: "deactivate") - - ModerationLog.insert_log(%{ - actor: admin, - subject: user, - action: action - }) - - json_response(conn, :no_content, "") - 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_follow(%{assigns: %{user: admin}} = conn, %{"relay_url" => target}) do diff --git a/lib/pleroma/web/admin_api/views/account_view.ex b/lib/pleroma/web/admin_api/views/account_view.ex index a96affd40..441269162 100644 --- a/lib/pleroma/web/admin_api/views/account_view.ex +++ b/lib/pleroma/web/admin_api/views/account_view.ex @@ -19,6 +19,12 @@ defmodule Pleroma.Web.AdminAPI.AccountView do } end + def render("index.json", %{users: users}) do + %{ + users: render_many(users, AccountView, "show.json", as: :user) + } + end + def render("show.json", %{user: user}) do avatar = User.avatar_url(user) |> MediaProxy.url() display_name = HTML.strip_tags(user.name || user.nickname) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index ae799b8ac..80651f3ff 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -137,11 +137,14 @@ defmodule Pleroma.Web.Router do delete("/users", AdminAPIController, :user_delete) post("/users", AdminAPIController, :users_create) patch("/users/:nickname/toggle_activation", AdminAPIController, :user_toggle_activation) + patch("/users/activate", AdminAPIController, :user_activate) + patch("/users/deactivate", AdminAPIController, :user_deactivate) put("/users/tag", AdminAPIController, :tag_users) delete("/users/tag", AdminAPIController, :untag_users) get("/users/:nickname/permission_group", AdminAPIController, :right_get) get("/users/:nickname/permission_group/:permission_group", AdminAPIController, :right_get) + post("/users/:nickname/permission_group/:permission_group", AdminAPIController, :right_add) delete( @@ -150,7 +153,13 @@ defmodule Pleroma.Web.Router do :right_delete ) - put("/users/:nickname/activation_status", AdminAPIController, :set_activation_status) + post("/users/permission_group/:permission_group", AdminAPIController, :right_add_multiple) + + delete( + "/users/permission_group/:permission_group", + AdminAPIController, + :right_delete_multiple + ) post("/relay", AdminAPIController, :relay_follow) delete("/relay", AdminAPIController, :relay_unfollow) |