Browse Source

[#394] Added `users.tags` and admin routes to tag and untag users. Added tests.

tags/v0.9.9
Ivan Tashkinov 5 years ago
parent
commit
7b19487389
8 changed files with 139 additions and 2 deletions
  1. +43
    -0
      lib/pleroma/user.ex
  2. +12
    -0
      lib/pleroma/web/admin_api/admin_api_controller.ex
  3. +9
    -0
      lib/pleroma/web/controller_helper.ex
  4. +3
    -1
      lib/pleroma/web/mastodon_api/views/account_view.ex
  5. +2
    -0
      lib/pleroma/web/router.ex
  6. +3
    -1
      lib/pleroma/web/twitter_api/views/user_view.ex
  7. +11
    -0
      priv/repo/migrations/20181206125616_add_tags_to_users.exs
  8. +56
    -0
      test/web/admin_api/admin_api_controller_test.exs

+ 43
- 0
lib/pleroma/user.ex View File

@@ -23,6 +23,7 @@ defmodule Pleroma.User do
field(:local, :boolean, default: true)
field(:follower_address, :string)
field(:search_distance, :float, virtual: true)
field(:tags, {:array, :string}, default: [])
field(:last_refreshed_at, :naive_datetime)
has_many(:notifications, Notification)
embeds_one(:info, Pleroma.User.Info)
@@ -819,4 +820,46 @@ defmodule Pleroma.User do

CommonUtils.format_input(bio, mentions, tags, "text/plain") |> Formatter.emojify(emoji)
end

def tag(user_identifiers, tags), do: tag_or_untag(user_identifiers, tags, :tag)

def untag(user_identifiers, tags), do: tag_or_untag(user_identifiers, tags, :untag)

defp tag_or_untag(user_identifier, tags, action) when not is_list(user_identifier),
do: tag_or_untag([user_identifier], tags, action)

defp tag_or_untag([hd | _] = nicknames, tags, action) when is_binary(hd) do
users = Repo.all(from(u in User, where: u.nickname in ^nicknames))

if length(users) == length(nicknames) do
tag_or_untag(users, tags, action)
else
{:error, :not_found}
end
end

defp tag_or_untag([hd | _] = users, tags, action) when is_map(hd) do
tags =
[tags]
|> List.flatten()
|> Enum.map(&String.downcase(&1))

Repo.transaction(fn ->
for user <- users do
new_tags =
if action == :tag do
Enum.uniq(user.tags ++ tags)
else
user.tags -- tags
end

{:ok, updated_user} =
user
|> change(%{tags: new_tags})
|> Repo.update()

updated_user
end
end)
end
end

+ 12
- 0
lib/pleroma/web/admin_api/admin_api_controller.ex View File

@@ -3,6 +3,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
alias Pleroma.{User, Repo}
alias Pleroma.Web.ActivityPub.Relay

import Pleroma.Web.ControllerHelper, only: [json_response: 3]

require Logger

action_fallback(:errors)
@@ -40,6 +42,16 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|> json(new_user.nickname)
end

def tag_users(conn, %{"nicknames" => nicknames, "tags" => tags}) do
with {:ok, _} <- User.tag(nicknames, tags),
do: json_response(conn, :no_content, "")
end

def untag_users(conn, %{"nicknames" => nicknames, "tags" => tags}) do
with {:ok, _} <- User.untag(nicknames, tags),
do: json_response(conn, :no_content, "")
end

def right_add(conn, %{"permission_group" => permission_group, "nickname" => nickname})
when permission_group in ["moderator", "admin"] do
user = User.get_by_nickname(nickname)


+ 9
- 0
lib/pleroma/web/controller_helper.ex View File

@@ -0,0 +1,9 @@
defmodule Pleroma.Web.ControllerHelper do
use Pleroma.Web, :controller

def json_response(conn, status, json) do
conn
|> put_status(status)
|> json(json)
end
end

+ 3
- 1
lib/pleroma/web/mastodon_api/views/account_view.ex View File

@@ -58,7 +58,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
note: "",
privacy: user_info.default_scope,
sensitive: false
}
},
# Note: Mastodon does not return this field:
tags: user.tags
}
end



+ 2
- 0
lib/pleroma/web/router.ex View File

@@ -98,6 +98,8 @@ defmodule Pleroma.Web.Router do
pipe_through(:admin_api)
delete("/user", AdminAPIController, :user_delete)
post("/user", AdminAPIController, :user_create)
put("/users/tag", AdminAPIController, :tag_users)
put("/users/untag", AdminAPIController, :untag_users)

get("/permission_group/:nickname", AdminAPIController, :right_get)
get("/permission_group/:nickname/:permission_group", AdminAPIController, :right_get)


+ 3
- 1
lib/pleroma/web/twitter_api/views/user_view.ex View File

@@ -77,7 +77,9 @@ defmodule Pleroma.Web.TwitterAPI.UserView do
"locked" => user.info.locked,
"default_scope" => user.info.default_scope,
"no_rich_text" => user.info.no_rich_text,
"fields" => fields
"fields" => fields,
# Note: twitter.com does not return this field:
"tags" => user.tags
}

if assigns[:token] do


+ 11
- 0
priv/repo/migrations/20181206125616_add_tags_to_users.exs View File

@@ -0,0 +1,11 @@
defmodule Pleroma.Repo.Migrations.AddTagsToUsers do
use Ecto.Migration

def change do
alter table(:users) do
add :tags, {:array, :string}
end

create index(:users, [:tags], using: :gin)
end
end

+ 56
- 0
test/web/admin_api/admin_api_controller_test.exs View File

@@ -37,6 +37,62 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
end
end

describe "/api/pleroma/admin//users/tag" do
setup do
admin = insert(:user, info: %{is_admin: true})
user1 = insert(:user, %{tags: ["x"]})
user2 = insert(:user, %{tags: ["y"]})
user3 = insert(:user, %{tags: ["unchanged"]})

conn =
build_conn()
|> assign(:user, admin)
|> 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, user1: user1, user2: user2} do
assert json_response(conn, :no_content)
assert Repo.get(User, user1.id).tags == ["x", "foo", "bar"]
assert Repo.get(User, user2.id).tags == ["y", "foo", "bar"]
end

test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
assert json_response(conn, :no_content)
assert Repo.get(User, user3.id).tags == ["unchanged"]
end
end

describe "/api/pleroma/admin//users/untag" do
setup do
admin = insert(:user, info: %{is_admin: true})
user1 = insert(:user, %{tags: ["x"]})
user2 = insert(:user, %{tags: ["y", "z"]})
user3 = insert(:user, %{tags: ["unchanged"]})

conn =
build_conn()
|> assign(:user, admin)
|> put_req_header("accept", "application/json")
|> put("/api/pleroma/admin/users/untag?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, user1: user1, user2: user2} do
assert json_response(conn, :no_content)
assert Repo.get(User, user1.id).tags == []
assert Repo.get(User, user2.id).tags == ["y"]
end

test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
assert json_response(conn, :no_content)
assert Repo.get(User, user3.id).tags == ["unchanged"]
end
end

describe "/api/pleroma/admin/permission_group" do
test "GET is giving user_info" do
admin = insert(:user, info: %{is_admin: true})


Loading…
Cancel
Save