forked from AkkomaGang/akkoma
Merge branch 'fix/1726-user-pagination' into 'develop'
Pagination fix for service users filters in admin api Closes #1726 See merge request pleroma/pleroma!2452
This commit is contained in:
commit
c3f1ce80eb
4 changed files with 49 additions and 30 deletions
|
@ -45,6 +45,7 @@ defmodule Pleroma.User.Query do
|
||||||
is_admin: boolean(),
|
is_admin: boolean(),
|
||||||
is_moderator: boolean(),
|
is_moderator: boolean(),
|
||||||
super_users: boolean(),
|
super_users: boolean(),
|
||||||
|
exclude_service_users: boolean(),
|
||||||
followers: User.t(),
|
followers: User.t(),
|
||||||
friends: User.t(),
|
friends: User.t(),
|
||||||
recipients_from_activity: [String.t()],
|
recipients_from_activity: [String.t()],
|
||||||
|
@ -88,6 +89,10 @@ defp compose_query({key, value}, query)
|
||||||
where(query, [u], ilike(field(u, ^key), ^"%#{value}%"))
|
where(query, [u], ilike(field(u, ^key), ^"%#{value}%"))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp compose_query({:exclude_service_users, _}, query) do
|
||||||
|
where(query, [u], not like(u.ap_id, "%/relay") and not like(u.ap_id, "%/internal/fetch"))
|
||||||
|
end
|
||||||
|
|
||||||
defp compose_query({key, value}, query)
|
defp compose_query({key, value}, query)
|
||||||
when key in @equal_criteria and not_empty_string(value) do
|
when key in @equal_criteria and not_empty_string(value) do
|
||||||
where(query, [u], ^[{key, value}])
|
where(query, [u], ^[{key, value}])
|
||||||
|
@ -98,7 +103,7 @@ defp compose_query({key, values}, query) when key in @contains_criteria and is_l
|
||||||
end
|
end
|
||||||
|
|
||||||
defp compose_query({:tags, tags}, query) when is_list(tags) and length(tags) > 0 do
|
defp compose_query({:tags, tags}, query) when is_list(tags) and length(tags) > 0 do
|
||||||
Enum.reduce(tags, query, &prepare_tag_criteria/2)
|
where(query, [u], fragment("? && ?", u.tags, ^tags))
|
||||||
end
|
end
|
||||||
|
|
||||||
defp compose_query({:is_admin, _}, query) do
|
defp compose_query({:is_admin, _}, query) do
|
||||||
|
@ -192,10 +197,6 @@ defp compose_query({:limit, limit}, query) do
|
||||||
|
|
||||||
defp compose_query(_unsupported_param, query), do: query
|
defp compose_query(_unsupported_param, query), do: query
|
||||||
|
|
||||||
defp prepare_tag_criteria(tag, query) do
|
|
||||||
or_where(query, [u], fragment("? = any(?)", ^tag, u.tags))
|
|
||||||
end
|
|
||||||
|
|
||||||
defp location_query(query, local) do
|
defp location_query(query, local) do
|
||||||
where(query, [u], u.local == ^local)
|
where(query, [u], u.local == ^local)
|
||||||
|> where([u], not is_nil(u.nickname))
|
|> where([u], not is_nil(u.nickname))
|
||||||
|
|
|
@ -392,29 +392,12 @@ def list_users(conn, params) do
|
||||||
email: params["email"]
|
email: params["email"]
|
||||||
}
|
}
|
||||||
|
|
||||||
with {:ok, users, count} <- Search.user(Map.merge(search_params, filters)),
|
with {:ok, users, count} <- Search.user(Map.merge(search_params, filters)) do
|
||||||
{:ok, users, count} <- filter_service_users(users, count),
|
json(
|
||||||
do:
|
conn,
|
||||||
conn
|
AccountView.render("index.json", users: users, count: count, page_size: page_size)
|
||||||
|> json(
|
|
||||||
AccountView.render("index.json",
|
|
||||||
users: users,
|
|
||||||
count: count,
|
|
||||||
page_size: page_size
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp filter_service_users(users, count) do
|
|
||||||
filtered_users = Enum.reject(users, &service_user?/1)
|
|
||||||
count = if Enum.any?(users, &service_user?/1), do: length(filtered_users), else: count
|
|
||||||
|
|
||||||
{:ok, filtered_users, count}
|
|
||||||
end
|
|
||||||
|
|
||||||
defp service_user?(user) do
|
|
||||||
String.match?(user.ap_id, ~r/.*\/relay$/) or
|
|
||||||
String.match?(user.ap_id, ~r/.*\/internal\/fetch$/)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@filters ~w(local external active deactivated is_admin is_moderator)
|
@filters ~w(local external active deactivated is_admin is_moderator)
|
||||||
|
|
|
@ -21,6 +21,7 @@ def user(params \\ %{}) do
|
||||||
query =
|
query =
|
||||||
params
|
params
|
||||||
|> Map.drop([:page, :page_size])
|
|> Map.drop([:page, :page_size])
|
||||||
|
|> Map.put(:exclude_service_users, true)
|
||||||
|> User.Query.build()
|
|> User.Query.build()
|
||||||
|> order_by([u], u.nickname)
|
|> order_by([u], u.nickname)
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
||||||
alias Pleroma.Tests.ObanHelpers
|
alias Pleroma.Tests.ObanHelpers
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.UserInviteToken
|
alias Pleroma.UserInviteToken
|
||||||
|
alias Pleroma.Web
|
||||||
alias Pleroma.Web.ActivityPub.Relay
|
alias Pleroma.Web.ActivityPub.Relay
|
||||||
alias Pleroma.Web.CommonAPI
|
alias Pleroma.Web.CommonAPI
|
||||||
alias Pleroma.Web.MediaProxy
|
alias Pleroma.Web.MediaProxy
|
||||||
|
@ -737,6 +738,39 @@ test "renders users array for the first page", %{conn: conn, admin: admin} do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "pagination works correctly with service users", %{conn: conn} do
|
||||||
|
service1 = insert(:user, ap_id: Web.base_url() <> "/relay")
|
||||||
|
service2 = insert(:user, ap_id: Web.base_url() <> "/internal/fetch")
|
||||||
|
insert_list(25, :user)
|
||||||
|
|
||||||
|
assert %{"count" => 26, "page_size" => 10, "users" => users1} =
|
||||||
|
conn
|
||||||
|
|> get("/api/pleroma/admin/users?page=1&filters=", %{page_size: "10"})
|
||||||
|
|> json_response(200)
|
||||||
|
|
||||||
|
assert Enum.count(users1) == 10
|
||||||
|
assert service1 not in [users1]
|
||||||
|
assert service2 not in [users1]
|
||||||
|
|
||||||
|
assert %{"count" => 26, "page_size" => 10, "users" => users2} =
|
||||||
|
conn
|
||||||
|
|> get("/api/pleroma/admin/users?page=2&filters=", %{page_size: "10"})
|
||||||
|
|> json_response(200)
|
||||||
|
|
||||||
|
assert Enum.count(users2) == 10
|
||||||
|
assert service1 not in [users2]
|
||||||
|
assert service2 not in [users2]
|
||||||
|
|
||||||
|
assert %{"count" => 26, "page_size" => 10, "users" => users3} =
|
||||||
|
conn
|
||||||
|
|> get("/api/pleroma/admin/users?page=3&filters=", %{page_size: "10"})
|
||||||
|
|> json_response(200)
|
||||||
|
|
||||||
|
assert Enum.count(users3) == 6
|
||||||
|
assert service1 not in [users3]
|
||||||
|
assert service2 not in [users3]
|
||||||
|
end
|
||||||
|
|
||||||
test "renders empty array for the second page", %{conn: conn} do
|
test "renders empty array for the second page", %{conn: conn} do
|
||||||
insert(:user)
|
insert(:user)
|
||||||
|
|
||||||
|
@ -3545,7 +3579,7 @@ test "errors", %{conn: conn} do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "success", %{conn: conn} do
|
test "success", %{conn: conn} do
|
||||||
base_url = Pleroma.Web.base_url()
|
base_url = Web.base_url()
|
||||||
app_name = "Trusted app"
|
app_name = "Trusted app"
|
||||||
|
|
||||||
response =
|
response =
|
||||||
|
@ -3566,7 +3600,7 @@ test "success", %{conn: conn} do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "with trusted", %{conn: conn} do
|
test "with trusted", %{conn: conn} do
|
||||||
base_url = Pleroma.Web.base_url()
|
base_url = Web.base_url()
|
||||||
app_name = "Trusted app"
|
app_name = "Trusted app"
|
||||||
|
|
||||||
response =
|
response =
|
||||||
|
|
Loading…
Reference in a new issue