Ability to toggle activation status and permission group for a group of users

This commit is contained in:
Maxim Filippov 2019-10-09 17:03:54 +03:00
parent 44e0c5cabb
commit ad42837244
9 changed files with 189 additions and 183 deletions

View file

@ -20,6 +20,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Changed ### Changed
- **Breaking:** Elixir >=1.8 is now required (was >= 1.7) - **Breaking:** Elixir >=1.8 is now required (was >= 1.7)
- **Breaking:** Admin API: Return link alongside with token on password reset - **Breaking:** Admin API: Return link alongside with token on password reset
- **Breaking:** Admin API: `/users/:nickname/toggle_activation` endpoint was split into two: `/users/activate`, `/users/deactivate`, both accept `nicknames` array
- **Breaking:** Admin API: `POST /users/permission_group/:permission_group` / `DELETE /users/permission_group/:permission_group` now accept `nicknames` array
- Replaced [pleroma_job_queue](https://git.pleroma.social/pleroma/pleroma_job_queue) and `Pleroma.Web.Federator.RetryQueue` with [Oban](https://github.com/sorentwo/oban) (see [`docs/config.md`](docs/config.md) on migrating customized worker / retry settings) - Replaced [pleroma_job_queue](https://git.pleroma.social/pleroma/pleroma_job_queue) and `Pleroma.Web.Federator.RetryQueue` with [Oban](https://github.com/sorentwo/oban) (see [`docs/config.md`](docs/config.md) on migrating customized worker / retry settings)
- Introduced [quantum](https://github.com/quantum-elixir/quantum-core) job scheduler - Introduced [quantum](https://github.com/quantum-elixir/quantum-core) job scheduler
- Admin API: Return `total` when querying for reports - Admin API: Return `total` when querying for reports
@ -40,6 +42,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Removed ### Removed
- **Breaking:** GNU Social API with Qvitter extensions support - **Breaking:** GNU Social API with Qvitter extensions support
- **Breaking:** Admin API: `/users/:nickname/activation_status` was removed in favor of `/users/activate`, `/users/deactivate`
- Emoji: Remove longfox emojis. - Emoji: Remove longfox emojis.
- Remove `Reply-To` header from report emails for admins. - Remove `Reply-To` header from report emails for admins.

View file

@ -154,31 +154,62 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
} }
``` ```
## `POST /api/pleroma/admin/users/permission_group/:permission_group`
### Add user in permission group ### Add user in permission group
- Method: `POST` - Params:
- Params: none - `nicknames`: nicknames array
- Response: - Response:
- On failure: `{"error": "…"}` - On failure: `{"error": "…"}`
- On success: JSON of the `user.info` - On success: JSON of the `user.info`
## `DELETE /api/pleroma/admin/users/permission_group/:permission_group`
### Remove user from permission group ### Remove user from permission group
- Method: `DELETE` - Params:
- Params: none - `nicknames`: nicknames array
- Response: - Response:
- On failure: `{"error": "…"}` - On failure: `{"error": "…"}`
- On success: JSON of the `user.info` - On success: JSON of the `user.info`
- Note: An admin cannot revoke their own admin status. - Note: An admin cannot revoke their own admin status.
## `/api/pleroma/admin/users/:nickname/activation_status` ## `PATCH /api/pleroma/admin/users/activate`
### Active or deactivate a user ### Activate user
- Method: `PUT`
- Params: - Params:
- `nickname` - `nicknames`: nicknames array
- `status` BOOLEAN field, false value means deactivation. - Response:
```json
{
users: [
{
// user object
}
]
}
```
## `PATCH /api/pleroma/admin/users/deactivate`
### Deactivate user
- Params:
- `nicknames`: nicknames array
- Response:
```json
{
users: [
{
// user object
}
]
}
```
## `/api/pleroma/admin/users/:nickname_or_id` ## `/api/pleroma/admin/users/:nickname_or_id`

View file

@ -86,18 +86,18 @@ defp parse_datetime(datetime) do
parsed_datetime parsed_datetime
end 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} {:ok, ModerationLog} | {:error, any}
def insert_log(%{ def insert_log(%{
actor: %User{} = actor, actor: %User{} = actor,
subject: %User{} = subject, subject: subjects,
action: action, action: action,
permission: permission permission: permission
}) do }) do
%ModerationLog{ %ModerationLog{
data: %{ data: %{
"actor" => user_to_map(actor), "actor" => user_to_map(actor),
"subject" => user_to_map(subject), "subject" => user_to_map(subjects),
"action" => action, "action" => action,
"permission" => permission, "permission" => permission,
"message" => "" "message" => ""
@ -303,13 +303,16 @@ def insert_log(%{
end end
@spec insert_log_entry_with_message(ModerationLog) :: {:ok, ModerationLog} | {:error, any} @spec insert_log_entry_with_message(ModerationLog) :: {:ok, ModerationLog} | {:error, any}
defp insert_log_entry_with_message(entry) do defp insert_log_entry_with_message(entry) do
entry.data["message"] entry.data["message"]
|> put_in(get_log_entry_message(entry)) |> put_in(get_log_entry_message(entry))
|> Repo.insert() |> Repo.insert()
end 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 defp user_to_map(%User{} = user) do
user user
|> Map.from_struct() |> Map.from_struct()
@ -363,12 +366,7 @@ def get_log_entry_message(%ModerationLog{
"subjects" => subjects "subjects" => subjects
} }
}) do }) do
nicknames = "@#{actor_nickname} created users: #{users_to_nicknames_string(subjects)}"
subjects
|> Enum.map(&"@#{&1["nickname"]}")
|> Enum.join(", ")
"@#{actor_nickname} created users: #{nicknames}"
end end
@spec get_log_entry_message(ModerationLog) :: String.t() @spec get_log_entry_message(ModerationLog) :: String.t()
@ -376,10 +374,10 @@ def get_log_entry_message(%ModerationLog{
data: %{ data: %{
"actor" => %{"nickname" => actor_nickname}, "actor" => %{"nickname" => actor_nickname},
"action" => "activate", "action" => "activate",
"subject" => %{"nickname" => subject_nickname, "type" => "user"} "subject" => users
} }
}) do }) do
"@#{actor_nickname} activated user @#{subject_nickname}" "@#{actor_nickname} activated users: #{users_to_nicknames_string(users)}"
end end
@spec get_log_entry_message(ModerationLog) :: String.t() @spec get_log_entry_message(ModerationLog) :: String.t()
@ -387,10 +385,10 @@ def get_log_entry_message(%ModerationLog{
data: %{ data: %{
"actor" => %{"nickname" => actor_nickname}, "actor" => %{"nickname" => actor_nickname},
"action" => "deactivate", "action" => "deactivate",
"subject" => %{"nickname" => subject_nickname, "type" => "user"} "subject" => users
} }
}) do }) do
"@#{actor_nickname} deactivated user @#{subject_nickname}" "@#{actor_nickname} deactivated users: #{users_to_nicknames_string(users)}"
end end
@spec get_log_entry_message(ModerationLog) :: String.t() @spec get_log_entry_message(ModerationLog) :: String.t()
@ -402,14 +400,9 @@ def get_log_entry_message(%ModerationLog{
"action" => "tag" "action" => "tag"
} }
}) do }) do
nicknames_string =
nicknames
|> Enum.map(&"@#{&1}")
|> Enum.join(", ")
tags_string = tags |> 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 end
@spec get_log_entry_message(ModerationLog) :: String.t() @spec get_log_entry_message(ModerationLog) :: String.t()
@ -421,14 +414,9 @@ def get_log_entry_message(%ModerationLog{
"action" => "untag" "action" => "untag"
} }
}) do }) do
nicknames_string =
nicknames
|> Enum.map(&"@#{&1}")
|> Enum.join(", ")
tags_string = tags |> 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 end
@spec get_log_entry_message(ModerationLog) :: String.t() @spec get_log_entry_message(ModerationLog) :: String.t()
@ -436,11 +424,11 @@ def get_log_entry_message(%ModerationLog{
data: %{ data: %{
"actor" => %{"nickname" => actor_nickname}, "actor" => %{"nickname" => actor_nickname},
"action" => "grant", "action" => "grant",
"subject" => %{"nickname" => subject_nickname}, "subject" => users,
"permission" => permission "permission" => permission
} }
}) do }) do
"@#{actor_nickname} made @#{subject_nickname} #{permission}" "@#{actor_nickname} made #{users_to_nicknames_string(users)} #{permission}"
end end
@spec get_log_entry_message(ModerationLog) :: String.t() @spec get_log_entry_message(ModerationLog) :: String.t()
@ -448,11 +436,11 @@ def get_log_entry_message(%ModerationLog{
data: %{ data: %{
"actor" => %{"nickname" => actor_nickname}, "actor" => %{"nickname" => actor_nickname},
"action" => "revoke", "action" => "revoke",
"subject" => %{"nickname" => subject_nickname}, "subject" => users,
"permission" => permission "permission" => permission
} }
}) do }) do
"@#{actor_nickname} revoked #{permission} role from @#{subject_nickname}" "@#{actor_nickname} revoked #{permission} role from #{users_to_nicknames_string(users)}"
end end
@spec get_log_entry_message(ModerationLog) :: String.t() @spec get_log_entry_message(ModerationLog) :: String.t()
@ -551,4 +539,16 @@ def get_log_entry_message(%ModerationLog{
}) do }) do
"@#{actor_nickname} deleted status ##{subject_id}" "@#{actor_nickname} deleted status ##{subject_id}"
end 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 end

View file

@ -1059,7 +1059,15 @@ def deactivate_async(user, status \\ true) do
BackgroundWorker.enqueue("deactivate_user", %{"user_id" => user.id, "status" => status}) BackgroundWorker.enqueue("deactivate_user", %{"user_id" => user.id, "status" => status})
end 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 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_followers(user), &invalidate_cache/1)
Enum.each(get_friends(user), &update_follower_count/1) Enum.each(get_friends(user), &update_follower_count/1)
@ -1625,6 +1633,12 @@ def change_info(user, fun) do
`fun` is called with the `user.info`. `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 def update_info(user, fun) do
user user
|> change_info(fun) |> change_info(fun)

View file

@ -231,22 +231,34 @@ def list_user_statuses(conn, %{"nickname" => nickname} = params) do
end end
end end
def user_toggle_activation(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do def user_activate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
user = User.get_cached_by_nickname(nickname) users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
{:ok, updated_users} = User.deactivate(users, false)
{:ok, updated_user} = User.deactivate(user, !user.info.deactivated)
action = if user.info.deactivated, do: "activate", else: "deactivate"
ModerationLog.insert_log(%{ ModerationLog.insert_log(%{
actor: admin, actor: admin,
subject: user, subject: users,
action: action action: "activate"
}) })
conn conn
|> put_view(AccountView) |> put_view(AccountView)
|> render("show.json", %{user: updated_user}) |> 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 end
def tag_users(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames, "tags" => tags}) do def tag_users(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames, "tags" => tags}) do
@ -315,20 +327,19 @@ defp maybe_parse_filters(filters) do
def right_add(%{assigns: %{user: admin}} = conn, %{ def right_add(%{assigns: %{user: admin}} = conn, %{
"permission_group" => permission_group, "permission_group" => permission_group,
"nickname" => nickname "nicknames" => nicknames
}) })
when permission_group in ["moderator", "admin"] do when permission_group in ["moderator", "admin"] do
info = Map.put(%{}, "is_" <> permission_group, true) info = Map.put(%{}, "is_" <> permission_group, true)
{:ok, user} = users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
nickname
|> User.get_cached_by_nickname() User.update_info(users, &User.Info.admin_api_update(&1, info))
|> User.update_info(&User.Info.admin_api_update(&1, info))
ModerationLog.insert_log(%{ ModerationLog.insert_log(%{
action: "grant", action: "grant",
actor: admin, actor: admin,
subject: user, subject: users,
permission: permission_group permission: permission_group
}) })
@ -349,58 +360,38 @@ def right_get(conn, %{"nickname" => nickname}) do
}) })
end 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 right_delete( def right_delete(
%{assigns: %{user: admin}} = conn, %{assigns: %{user: %{nickname: admin_nickname} = admin}} = conn,
%{ %{
"permission_group" => permission_group, "permission_group" => permission_group,
"nickname" => nickname "nicknames" => nicknames
} }
) )
when permission_group in ["moderator", "admin"] do when permission_group in ["moderator", "admin"] do
with false <- Enum.member?(nicknames, admin_nickname) do
info = Map.put(%{}, "is_" <> permission_group, false) info = Map.put(%{}, "is_" <> permission_group, false)
{:ok, user} = users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
nickname
|> User.get_cached_by_nickname() User.update_info(users, &User.Info.admin_api_update(&1, info))
|> User.update_info(&User.Info.admin_api_update(&1, info))
ModerationLog.insert_log(%{ ModerationLog.insert_log(%{
action: "revoke", action: "revoke",
actor: admin, actor: admin,
subject: user, subject: users,
permission: permission_group permission: permission_group
}) })
json(conn, info) json(conn, info)
else
_ -> render_error(conn, :forbidden, "You can't revoke your own admin/moderator status.")
end
end end
def right_delete(conn, _) do def right_delete(conn, _) do
render_error(conn, :not_found, "No such permission_group") render_error(conn, :not_found, "No such permission_group")
end 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
end
def relay_follow(%{assigns: %{user: admin}} = conn, %{"relay_url" => target}) do def relay_follow(%{assigns: %{user: admin}} = conn, %{"relay_url" => target}) do
with {:ok, _message} <- Relay.follow(target) do with {:ok, _message} <- Relay.follow(target) do
ModerationLog.insert_log(%{ ModerationLog.insert_log(%{

View file

@ -19,6 +19,12 @@ def render("index.json", %{users: users, count: count, page_size: page_size}) do
} }
end 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 def render("show.json", %{user: user}) do
avatar = User.avatar_url(user) |> MediaProxy.url() avatar = User.avatar_url(user) |> MediaProxy.url()
display_name = HTML.strip_tags(user.name || user.nickname) display_name = HTML.strip_tags(user.name || user.nickname)

View file

@ -136,21 +136,15 @@ defmodule Pleroma.Web.Router do
delete("/users", AdminAPIController, :user_delete) delete("/users", AdminAPIController, :user_delete)
post("/users", AdminAPIController, :users_create) 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) put("/users/tag", AdminAPIController, :tag_users)
delete("/users/tag", AdminAPIController, :untag_users) delete("/users/tag", AdminAPIController, :untag_users)
get("/users/:nickname/permission_group", AdminAPIController, :right_get) get("/users/:nickname/permission_group", AdminAPIController, :right_get)
get("/users/:nickname/permission_group/: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) post("/users/permission_group/:permission_group", AdminAPIController, :right_add)
delete("/users/permission_group/:permission_group", AdminAPIController, :right_delete)
delete(
"/users/:nickname/permission_group/:permission_group",
AdminAPIController,
:right_delete
)
put("/users/:nickname/activation_status", AdminAPIController, :set_activation_status)
post("/relay", AdminAPIController, :relay_follow) post("/relay", AdminAPIController, :relay_follow)
delete("/relay", AdminAPIController, :relay_unfollow) delete("/relay", AdminAPIController, :relay_unfollow)

View file

@ -128,7 +128,7 @@ test "logging user grant by moderator", %{moderator: moderator, subject1: subjec
{:ok, _} = {:ok, _} =
ModerationLog.insert_log(%{ ModerationLog.insert_log(%{
actor: moderator, actor: moderator,
subject: subject1, subject: [subject1],
action: "grant", action: "grant",
permission: "moderator" permission: "moderator"
}) })
@ -142,7 +142,7 @@ test "logging user revoke by moderator", %{moderator: moderator, subject1: subje
{:ok, _} = {:ok, _} =
ModerationLog.insert_log(%{ ModerationLog.insert_log(%{
actor: moderator, actor: moderator,
subject: subject1, subject: [subject1],
action: "revoke", action: "revoke",
permission: "moderator" permission: "moderator"
}) })

View file

@ -386,13 +386,16 @@ test "GET is giving user_info" do
test "/:right POST, can add to a permission group" do test "/:right POST, can add to a permission group" do
admin = insert(:user, info: %{is_admin: true}) admin = insert(:user, info: %{is_admin: true})
user = insert(:user) user_one = insert(:user)
user_two = insert(:user)
conn = conn =
build_conn() build_conn()
|> assign(:user, admin) |> assign(:user, admin)
|> put_req_header("accept", "application/json") |> put_req_header("accept", "application/json")
|> post("/api/pleroma/admin/users/#{user.nickname}/permission_group/admin") |> post("/api/pleroma/admin/users/permission_group/admin", %{
nicknames: [user_one.nickname, user_two.nickname]
})
assert json_response(conn, 200) == %{ assert json_response(conn, 200) == %{
"is_admin" => true "is_admin" => true
@ -401,18 +404,21 @@ test "/:right POST, can add to a permission group" do
log_entry = Repo.one(ModerationLog) log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) == assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} made @#{user.nickname} admin" "@#{admin.nickname} made @#{user_one.nickname}, @#{user_two.nickname} admin"
end end
test "/:right DELETE, can remove from a permission group" do test "/:right DELETE, can remove from a permission group" do
admin = insert(:user, info: %{is_admin: true}) admin = insert(:user, info: %{is_admin: true})
user = insert(:user, info: %{is_admin: true}) user_one = insert(:user, info: %{is_admin: true})
user_two = insert(:user, info: %{is_admin: true})
conn = conn =
build_conn() build_conn()
|> assign(:user, admin) |> assign(:user, admin)
|> put_req_header("accept", "application/json") |> put_req_header("accept", "application/json")
|> delete("/api/pleroma/admin/users/#{user.nickname}/permission_group/admin") |> delete("/api/pleroma/admin/users/permission_group/admin", %{
nicknames: [user_one.nickname, user_two.nickname]
})
assert json_response(conn, 200) == %{ assert json_response(conn, 200) == %{
"is_admin" => false "is_admin" => false
@ -421,65 +427,9 @@ test "/:right DELETE, can remove from a permission group" do
log_entry = Repo.one(ModerationLog) log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) == assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} revoked admin role from @#{user.nickname}" "@#{admin.nickname} revoked admin role from @#{user_one.nickname}, @#{
end user_two.nickname
end }"
describe "PUT /api/pleroma/admin/users/:nickname/activation_status" do
setup %{conn: conn} do
admin = insert(:user, info: %{is_admin: true})
conn =
conn
|> assign(:user, admin)
|> put_req_header("accept", "application/json")
%{conn: conn, admin: admin}
end
test "deactivates the user", %{conn: conn, admin: admin} do
user = insert(:user)
conn =
conn
|> put("/api/pleroma/admin/users/#{user.nickname}/activation_status", %{status: false})
user = User.get_cached_by_id(user.id)
assert user.info.deactivated == true
assert json_response(conn, :no_content)
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} deactivated user @#{user.nickname}"
end
test "activates the user", %{conn: conn, admin: admin} do
user = insert(:user, info: %{deactivated: true})
conn =
conn
|> put("/api/pleroma/admin/users/#{user.nickname}/activation_status", %{status: true})
user = User.get_cached_by_id(user.id)
assert user.info.deactivated == false
assert json_response(conn, :no_content)
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} activated user @#{user.nickname}"
end
test "returns 403 when requested by a non-admin", %{conn: conn} do
user = insert(:user)
conn =
conn
|> assign(:user, user)
|> put("/api/pleroma/admin/users/#{user.nickname}/activation_status", %{status: false})
assert json_response(conn, :forbidden)
end end
end end
@ -1029,31 +979,48 @@ test "it works with multiple filters" do
end end
end end
test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation" do test "PATCH /api/pleroma/admin/users/activate" do
admin = insert(:user, info: %{is_admin: true}) admin = insert(:user, info: %{is_admin: true})
user = insert(:user) user_one = insert(:user, info: %{deactivated: true})
user_two = insert(:user, info: %{deactivated: true})
conn = conn =
build_conn() build_conn()
|> assign(:user, admin) |> assign(:user, admin)
|> patch("/api/pleroma/admin/users/#{user.nickname}/toggle_activation") |> patch(
"/api/pleroma/admin/users/activate",
%{nicknames: [user_one.nickname, user_two.nickname]}
)
assert json_response(conn, 200) == response = json_response(conn, 200)
%{ assert Enum.map(response["users"], & &1["deactivated"]) == [false, false]
"deactivated" => !user.info.deactivated,
"id" => user.id,
"nickname" => user.nickname,
"roles" => %{"admin" => false, "moderator" => false},
"local" => true,
"tags" => [],
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname)
}
log_entry = Repo.one(ModerationLog) log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) == assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} deactivated user @#{user.nickname}" "@#{admin.nickname} activated users: @#{user_one.nickname}, @#{user_two.nickname}"
end
test "PATCH /api/pleroma/admin/users/deactivate" do
admin = insert(:user, info: %{is_admin: true})
user_one = insert(:user, info: %{deactivated: false})
user_two = insert(:user, info: %{deactivated: false})
conn =
build_conn()
|> assign(:user, admin)
|> patch(
"/api/pleroma/admin/users/deactivate",
%{nicknames: [user_one.nickname, user_two.nickname]}
)
response = json_response(conn, 200)
assert Enum.map(response["users"], & &1["deactivated"]) == [true, true]
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} deactivated users: @#{user_one.nickname}, @#{user_two.nickname}"
end end
describe "POST /api/pleroma/admin/users/invite_token" do describe "POST /api/pleroma/admin/users/invite_token" do