summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Gleason <alex@alexgleason.me>2021-11-26 15:19:01 -0600
committerAlex Gleason <alex@alexgleason.me>2021-11-26 15:19:01 -0600
commit6c0484d571e4ed4e39fa3f88e6e1d2d7b8de96fa (patch)
tree060de963fb213e8139c2eac39ab806470380ec7d
parente28d990ecba287d5c44ed04c0039b43c8f309e50 (diff)
AdminAPI: suggest a user through the API
-rw-r--r--docs/development/API/admin_api.md40
-rw-r--r--lib/pleroma/moderation_log.ex20
-rw-r--r--lib/pleroma/user.ex16
-rw-r--r--lib/pleroma/web/admin_api/controllers/user_controller.ex30
-rw-r--r--lib/pleroma/web/api_spec/operations/admin/user_operation.ex66
-rw-r--r--lib/pleroma/web/router.ex3
-rw-r--r--test/pleroma/user_test.exs32
-rw-r--r--test/pleroma/web/admin_api/controllers/user_controller_test.exs52
8 files changed, 257 insertions, 2 deletions
diff --git a/docs/development/API/admin_api.md b/docs/development/API/admin_api.md
index 8f855d251..79531c45b 100644
--- a/docs/development/API/admin_api.md
+++ b/docs/development/API/admin_api.md
@@ -261,6 +261,46 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
}
```
+## `PATCH /api/v1/pleroma/admin/users/suggest`
+
+### Suggest a user
+
+Adds the user(s) to follower recommendations.
+
+- Params:
+ - `nicknames`: nicknames array
+- Response:
+
+```json
+{
+ users: [
+ {
+ // user object
+ }
+ ]
+}
+```
+
+## `PATCH /api/v1/pleroma/admin/users/unsuggest`
+
+### Unsuggest a user
+
+Removes the user(s) from follower recommendations.
+
+- Params:
+ - `nicknames`: nicknames array
+- Response:
+
+```json
+{
+ users: [
+ {
+ // user object
+ }
+ ]
+}
+```
+
## `GET /api/v1/pleroma/admin/users/:nickname_or_id`
### Retrive the details of a user
diff --git a/lib/pleroma/moderation_log.ex b/lib/pleroma/moderation_log.ex
index 1849cacc8..ca032657c 100644
--- a/lib/pleroma/moderation_log.ex
+++ b/lib/pleroma/moderation_log.ex
@@ -341,6 +341,26 @@ defmodule Pleroma.ModerationLog do
def get_log_entry_message(%ModerationLog{
data: %{
"actor" => %{"nickname" => actor_nickname},
+ "action" => "add_suggestion",
+ "subject" => users
+ }
+ }) do
+ "@#{actor_nickname} added suggested users: #{users_to_nicknames_string(users)}"
+ end
+
+ def get_log_entry_message(%ModerationLog{
+ data: %{
+ "actor" => %{"nickname" => actor_nickname},
+ "action" => "remove_suggestion",
+ "subject" => users
+ }
+ }) do
+ "@#{actor_nickname} removed suggested users: #{users_to_nicknames_string(users)}"
+ end
+
+ def get_log_entry_message(%ModerationLog{
+ data: %{
+ "actor" => %{"nickname" => actor_nickname},
"nicknames" => nicknames,
"tags" => tags,
"action" => "tag"
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index 6d62e9b43..880f027bc 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -1678,6 +1678,22 @@ defmodule Pleroma.User do
def confirm(%User{} = user), do: {:ok, user}
+ def set_suggestion(users, is_suggested) when is_list(users) do
+ Repo.transaction(fn ->
+ Enum.map(users, fn user ->
+ with {:ok, user} <- set_suggestion(user, is_suggested), do: user
+ end)
+ end)
+ end
+
+ def set_suggestion(%User{is_suggested: is_suggested} = user, is_suggested), do: {:ok, user}
+
+ def set_suggestion(%User{} = user, is_suggested) when is_boolean(is_suggested) do
+ user
+ |> change(is_suggested: is_suggested)
+ |> update_and_set_cache()
+ end
+
def update_notification_settings(%User{} = user, settings) do
user
|> cast(%{notification_settings: settings}, [])
diff --git a/lib/pleroma/web/admin_api/controllers/user_controller.ex b/lib/pleroma/web/admin_api/controllers/user_controller.ex
index 637a0e702..50208a8b7 100644
--- a/lib/pleroma/web/admin_api/controllers/user_controller.ex
+++ b/lib/pleroma/web/admin_api/controllers/user_controller.ex
@@ -35,7 +35,9 @@ defmodule Pleroma.Web.AdminAPI.UserController do
:toggle_activation,
:activate,
:deactivate,
- :approve
+ :approve,
+ :suggest,
+ :unsuggest
]
)
@@ -239,6 +241,32 @@ defmodule Pleroma.Web.AdminAPI.UserController do
render(conn, "index.json", users: updated_users)
end
+ def suggest(%{assigns: %{user: admin}, body_params: %{nicknames: nicknames}} = conn, _) do
+ users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
+ {:ok, updated_users} = User.set_suggestion(users, true)
+
+ ModerationLog.insert_log(%{
+ actor: admin,
+ subject: users,
+ action: "add_suggestion"
+ })
+
+ render(conn, "index.json", users: updated_users)
+ end
+
+ def unsuggest(%{assigns: %{user: admin}, body_params: %{nicknames: nicknames}} = conn, _) do
+ users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
+ {:ok, updated_users} = User.set_suggestion(users, false)
+
+ ModerationLog.insert_log(%{
+ actor: admin,
+ subject: users,
+ action: "remove_suggestion"
+ })
+
+ render(conn, "index.json", users: updated_users)
+ end
+
def index(conn, params) do
{page, page_size} = page_params(params)
filters = maybe_parse_filters(params[:filters])
diff --git a/lib/pleroma/web/api_spec/operations/admin/user_operation.ex b/lib/pleroma/web/api_spec/operations/admin/user_operation.ex
index c9d0bfd7c..57fb1ad65 100644
--- a/lib/pleroma/web/api_spec/operations/admin/user_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/admin/user_operation.ex
@@ -216,7 +216,71 @@ defmodule Pleroma.Web.ApiSpec.Admin.UserOperation do
request_body(
"Parameters",
%Schema{
- description: "POST body for deleting multiple users",
+ description: "POST body for approving multiple users",
+ type: :object,
+ properties: %{
+ nicknames: %Schema{
+ type: :array,
+ items: %Schema{type: :string}
+ }
+ }
+ }
+ ),
+ responses: %{
+ 200 =>
+ Operation.response("Response", "application/json", %Schema{
+ type: :object,
+ properties: %{user: %Schema{type: :array, items: user()}}
+ }),
+ 403 => Operation.response("Forbidden", "application/json", ApiError)
+ }
+ }
+ end
+
+ def suggest_operation do
+ %Operation{
+ tags: ["User administration"],
+ summary: "Suggest multiple users",
+ operationId: "AdminAPI.UserController.suggest",
+ security: [%{"oAuth" => ["admin:write:accounts"]}],
+ parameters: admin_api_params(),
+ requestBody:
+ request_body(
+ "Parameters",
+ %Schema{
+ description: "POST body for adding multiple suggested users",
+ type: :object,
+ properties: %{
+ nicknames: %Schema{
+ type: :array,
+ items: %Schema{type: :string}
+ }
+ }
+ }
+ ),
+ responses: %{
+ 200 =>
+ Operation.response("Response", "application/json", %Schema{
+ type: :object,
+ properties: %{user: %Schema{type: :array, items: user()}}
+ }),
+ 403 => Operation.response("Forbidden", "application/json", ApiError)
+ }
+ }
+ end
+
+ def unsuggest_operation do
+ %Operation{
+ tags: ["User administration"],
+ summary: "Unsuggest multiple users",
+ operationId: "AdminAPI.UserController.unsuggest",
+ security: [%{"oAuth" => ["admin:write:accounts"]}],
+ parameters: admin_api_params(),
+ requestBody:
+ request_body(
+ "Parameters",
+ %Schema{
+ description: "POST body for removing multiple suggested users",
type: :object,
properties: %{
nicknames: %Schema{
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index acf9ce6c2..1f51bf456 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -194,6 +194,9 @@ defmodule Pleroma.Web.Router do
patch("/users/deactivate", UserController, :deactivate)
patch("/users/approve", UserController, :approve)
+ patch("/users/suggest", UserController, :suggest)
+ patch("/users/unsuggest", UserController, :unsuggest)
+
get("/relay", RelayController, :index)
post("/relay", RelayController, :follow)
delete("/relay", RelayController, :unfollow)
diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs
index 4021a565d..c6282db78 100644
--- a/test/pleroma/user_test.exs
+++ b/test/pleroma/user_test.exs
@@ -1720,6 +1720,38 @@ defmodule Pleroma.UserTest do
assert user.banner == %{}
end
+ describe "set_suggestion" do
+ test "suggests a user" do
+ user = insert(:user, is_suggested: false)
+ refute user.is_suggested
+ {:ok, user} = User.set_suggestion(user, true)
+ assert user.is_suggested
+ end
+
+ test "suggests a list of users" do
+ unsuggested_users = [
+ insert(:user, is_suggested: false),
+ insert(:user, is_suggested: false),
+ insert(:user, is_suggested: false)
+ ]
+
+ {:ok, users} = User.set_suggestion(unsuggested_users, true)
+
+ assert Enum.count(users) == 3
+
+ Enum.each(users, fn user ->
+ assert user.is_suggested
+ end)
+ end
+
+ test "unsuggests a user" do
+ user = insert(:user, is_suggested: true)
+ assert user.is_suggested
+ {:ok, user} = User.set_suggestion(user, false)
+ refute user.is_suggested
+ end
+ end
+
test "get_public_key_for_ap_id fetches a user that's not in the db" do
assert {:ok, _key} = User.get_public_key_for_ap_id("http://mastodon.example.org/users/admin")
end
diff --git a/test/pleroma/web/admin_api/controllers/user_controller_test.exs b/test/pleroma/web/admin_api/controllers/user_controller_test.exs
index d9da34f6e..df13f00e6 100644
--- a/test/pleroma/web/admin_api/controllers/user_controller_test.exs
+++ b/test/pleroma/web/admin_api/controllers/user_controller_test.exs
@@ -873,6 +873,58 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do
"@#{admin.nickname} approved users: @#{user_one.nickname}, @#{user_two.nickname}"
end
+ test "PATCH /api/pleroma/admin/users/suggest", %{admin: admin, conn: conn} do
+ user1 = insert(:user, is_suggested: false)
+ user2 = insert(:user, is_suggested: false)
+
+ _response =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> patch(
+ "/api/pleroma/admin/users/suggest",
+ %{nicknames: [user1.nickname, user2.nickname]}
+ )
+ |> json_response_and_validate_schema(200)
+
+ [user1, user2] = Repo.reload!([user1, user2])
+
+ assert user1.is_suggested
+ assert user2.is_suggested
+
+ log_entry = Repo.one(ModerationLog)
+
+ assert ModerationLog.get_log_entry_message(log_entry) ==
+ "@#{admin.nickname} added suggested users: @#{user1.nickname}, @#{
+ user2.nickname
+ }"
+ end
+
+ test "PATCH /api/pleroma/admin/users/unsuggest", %{admin: admin, conn: conn} do
+ user1 = insert(:user, is_suggested: true)
+ user2 = insert(:user, is_suggested: true)
+
+ _response =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> patch(
+ "/api/pleroma/admin/users/unsuggest",
+ %{nicknames: [user1.nickname, user2.nickname]}
+ )
+ |> json_response_and_validate_schema(200)
+
+ [user1, user2] = Repo.reload!([user1, user2])
+
+ refute user1.is_suggested
+ refute user2.is_suggested
+
+ log_entry = Repo.one(ModerationLog)
+
+ assert ModerationLog.get_log_entry_message(log_entry) ==
+ "@#{admin.nickname} removed suggested users: @#{user1.nickname}, @#{
+ user2.nickname
+ }"
+ end
+
test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation", %{admin: admin, conn: conn} do
user = insert(:user)