added /api/pleroma/admin/users/tag

This commit is contained in:
Maksim Pechnikov 2020-10-14 09:26:05 +03:00 committed by Alexander Strizhakov
parent a9bc652ab9
commit 35e8573483
No known key found for this signature in database
GPG Key ID: 022896A53AEF1381
8 changed files with 253 additions and 30 deletions

View File

@ -88,6 +88,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Mastodon API: `/api/v1/accounts/:id` & `/api/v1/mutes` endpoints accept `with_relationships` parameter and return filled `pleroma.relationship` field.
- Mastodon API: Endpoint to remove a conversation (`DELETE /api/v1/conversations/:id`).
- Mastodon API: `expires_in` in the scheduled post `params` field on `/api/v1/statuses` and `/api/v1/scheduled_statuses/:id` endpoints.
- Add `GET /api/pleroma/admin/users/tag` - returns a list of users tags.
</details>
### Fixed
@ -152,6 +153,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Security
- Fixed the possibility of using file uploads to spoof posts.
=======
- Mix tasks for controlling user account confirmation status in bulk (`mix pleroma.user confirm_all` and `mix pleroma.user unconfirm_all`)
- Mix task for sending confirmation emails to all unconfirmed users (`mix pleroma.email send_confirmation_mails`)
- Mix task option for force-unfollowing relays
### Changed

View File

@ -119,6 +119,19 @@ The `/api/v1/pleroma/admin/*` path is backwards compatible with `/api/pleroma/ad
}
```
## `GET /api/v1/pleroma/admin/users/tag`
### List tags
- Params: None
- Response:
``` json
["verify", "mrf_tag:media-force-nsfw"]
```
## `PUT /api/v1/pleroma/admin/users/tag`
### Tag a list of users

View File

@ -1259,6 +1259,15 @@ defmodule Pleroma.User do
|> Repo.all()
end
@spec list_tags() :: list(String.t())
def list_tags do
from(
u in __MODULE__,
select: type(fragment("DISTINCT unnest(?)", u.tags), :string)
)
|> Repo.all()
end
def increase_note_count(%User{} = user) do
User
|> where(id: ^user.id)

View File

@ -21,6 +21,17 @@ defmodule Pleroma.Web.ActivityPub.MRF.TagPolicy do
require Pleroma.Constants
def policy_tags do
[
"mrf_tag:media-force-nsfw",
"mrf_tag:media-strip",
"mrf_tag:force-unlisted",
"mrf_tag:sandbox",
"mrf_tag:disable-remote-subscription",
"mrf_tag:disable-any-subscription"
]
end
defp get_tags(%User{tags: tags}) when is_list(tags), do: tags
defp get_tags(_), do: []

View File

@ -35,8 +35,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
when action in [
:get_password_reset,
:force_password_reset,
:tag_users,
:untag_users,
:right_add,
:right_add_multiple,
:right_delete,
@ -138,32 +136,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
end
end
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(%{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 right_add_multiple(%{assigns: %{user: admin}} = conn, %{
"permission_group" => permission_group,
"nicknames" => nicknames

View File

@ -0,0 +1,62 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.AdminAPI.TagController do
use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper, only: [json_response: 3]
alias Pleroma.ModerationLog
alias Pleroma.User
alias Pleroma.Web.AdminAPI
alias Pleroma.Web.Plugs.OAuthScopesPlug
plug(
OAuthScopesPlug,
%{scopes: ["write:accounts"], admin: true} when action in [:tag, :untag]
)
plug(
OAuthScopesPlug,
%{scopes: ["read:accounts"], admin: true} when action in [:list]
)
action_fallback(AdminAPI.FallbackController)
def list(%{assigns: %{user: _admin}} = conn, _) do
tags =
Pleroma.User.list_tags()
|> Kernel.++(Pleroma.Web.ActivityPub.MRF.TagPolicy.policy_tags())
|> Enum.uniq()
|> Enum.sort()
json(conn, tags)
end
def tag(%{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(%{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
end

View File

@ -159,8 +159,9 @@ defmodule Pleroma.Web.Router do
pipe_through(:admin_api)
put("/users/disable_mfa", AdminAPIController, :disable_mfa)
put("/users/tag", AdminAPIController, :tag_users)
delete("/users/tag", AdminAPIController, :untag_users)
get("/users/tag", TagController, :list)
put("/users/tag", TagController, :tag)
delete("/users/tag", TagController, :untag)
get("/users/:nickname/permission_group", AdminAPIController, :right_get)
get("/users/:nickname/permission_group/:permission_group", AdminAPIController, :right_get)

View File

@ -0,0 +1,150 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.AdminAPI.TagControllerTest do
use Pleroma.Web.ConnCase
use Oban.Testing, repo: Pleroma.Repo
import Pleroma.Factory
alias Pleroma.ModerationLog
alias Pleroma.Repo
alias Pleroma.User
setup_all do
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
:ok
end
setup do
admin = insert(:user, is_admin: true)
token = insert(:oauth_admin_token, user: admin)
conn =
build_conn()
|> assign(:user, admin)
|> assign(:token, token)
{:ok, %{admin: admin, token: token, conn: conn}}
end
describe "GET /api/pleroma/admin/users/tag" do
test "it returns user tags and mrf policy tags", %{conn: conn} do
insert(:user, %{tags: ["x"]})
insert(:user, %{tags: ["y"]})
insert(:user, %{tags: ["unchanged"]})
response =
conn
|> put_req_header("accept", "application/json")
|> get("/api/pleroma/admin/users/tag")
|> json_response(200)
assert [
"mrf_tag:disable-any-subscription",
"mrf_tag:disable-remote-subscription",
"mrf_tag:force-unlisted",
"mrf_tag:media-force-nsfw",
"mrf_tag:media-strip",
"mrf_tag:sandbox",
"unchanged",
"x",
"y"
] == response
end
end
describe "PUT /api/pleroma/admin/users/tag" do
setup %{conn: conn} do
user1 = insert(:user, %{tags: ["x"]})
user2 = insert(:user, %{tags: ["y"]})
user3 = insert(:user, %{tags: ["unchanged"]})
conn =
conn
|> put_req_header("accept", "application/json")
|> put(
"/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <>
"#{user2.nickname}&tags[]=foo&tags[]=bar"
)
%{conn: conn, user1: user1, user2: user2, user3: user3}
end
test "it appends specified tags to users with specified nicknames", %{
conn: conn,
admin: admin,
user1: user1,
user2: user2
} do
assert empty_json_response(conn)
assert User.get_cached_by_id(user1.id).tags == ["x", "foo", "bar"]
assert User.get_cached_by_id(user2.id).tags == ["y", "foo", "bar"]
log_entry = Repo.one(ModerationLog)
users =
[user1.nickname, user2.nickname]
|> Enum.map(&"@#{&1}")
|> Enum.join(", ")
tags = ["foo", "bar"] |> Enum.join(", ")
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} added tags: #{tags} to users: #{users}"
end
test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
assert empty_json_response(conn)
assert User.get_cached_by_id(user3.id).tags == ["unchanged"]
end
end
describe "DELETE /api/pleroma/admin/users/tag" do
setup %{conn: conn} do
user1 = insert(:user, %{tags: ["x"]})
user2 = insert(:user, %{tags: ["y", "z"]})
user3 = insert(:user, %{tags: ["unchanged"]})
conn =
conn
|> put_req_header("accept", "application/json")
|> delete(
"/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <>
"#{user2.nickname}&tags[]=x&tags[]=z"
)
%{conn: conn, user1: user1, user2: user2, user3: user3}
end
test "it removes specified tags from users with specified nicknames", %{
conn: conn,
admin: admin,
user1: user1,
user2: user2
} do
assert empty_json_response(conn)
assert User.get_cached_by_id(user1.id).tags == []
assert User.get_cached_by_id(user2.id).tags == ["y"]
log_entry = Repo.one(ModerationLog)
users =
[user1.nickname, user2.nickname]
|> Enum.map(&"@#{&1}")
|> Enum.join(", ")
tags = ["x", "z"] |> Enum.join(", ")
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} removed tags: #{tags} from users: #{users}"
end
test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
assert empty_json_response(conn)
assert User.get_cached_by_id(user3.id).tags == ["unchanged"]
end
end
end