pagination fix for service users filters
authorAlexander Strizhakov <alex.strizhakov@gmail.com>
Fri, 1 May 2020 11:31:24 +0000 (14:31 +0300)
committerAlexander Strizhakov <alex.strizhakov@gmail.com>
Fri, 1 May 2020 11:31:24 +0000 (14:31 +0300)
lib/pleroma/user/query.ex
lib/pleroma/web/admin_api/admin_api_controller.ex
lib/pleroma/web/admin_api/search.ex
test/web/admin_api/admin_api_controller_test.exs

index ac77aab7134769f4b525c0df9ca4f9304bd9dc1a..3a3b047934d98e872ae4eb008a78e5237135048d 100644 (file)
@@ -45,6 +45,7 @@ defmodule Pleroma.User.Query do
             is_admin: boolean(),
             is_moderator: boolean(),
             super_users: boolean(),
+            exclude_service_users: boolean(),
             followers: User.t(),
             friends: User.t(),
             recipients_from_activity: [String.t()],
@@ -88,6 +89,10 @@ defmodule Pleroma.User.Query do
     where(query, [u], ilike(field(u, ^key), ^"%#{value}%"))
   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)
        when key in @equal_criteria and not_empty_string(value) do
     where(query, [u], ^[{key, value}])
@@ -98,7 +103,7 @@ defmodule Pleroma.User.Query do
   end
 
   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
 
   defp compose_query({:is_admin, _}, query) do
@@ -192,10 +197,6 @@ defmodule Pleroma.User.Query do
 
   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
     where(query, [u], u.local == ^local)
     |> where([u], not is_nil(u.nickname))
index 816c11e01f593ff8809811bb0fc461ff56776d9a..bfcc81cb881aac8128655644618b0b0f20de40d7 100644 (file)
@@ -392,29 +392,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
       email: params["email"]
     }
 
-    with {:ok, users, count} <- Search.user(Map.merge(search_params, filters)),
-         {:ok, users, count} <- filter_service_users(users, count),
-         do:
-           conn
-           |> json(
-             AccountView.render("index.json",
-               users: users,
-               count: count,
-               page_size: page_size
-             )
-           )
-  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$/)
+    with {:ok, users, count} <- Search.user(Map.merge(search_params, filters)) do
+      json(
+        conn,
+        AccountView.render("index.json", users: users, count: count, page_size: page_size)
+      )
+    end
   end
 
   @filters ~w(local external active deactivated is_admin is_moderator)
index 29cea1f44dbf59f5fba6cbf5ec7346d096c6e92a..c28efadd566e7a1905d6d00d9b29be7ebe78ce44 100644 (file)
@@ -21,6 +21,7 @@ defmodule Pleroma.Web.AdminAPI.Search do
     query =
       params
       |> Map.drop([:page, :page_size])
+      |> Map.put(:exclude_service_users, true)
       |> User.Query.build()
       |> order_by([u], u.nickname)
 
index f80dbf8dd9058d750c81a8eb1a79362130111c68..e3af01089584ed033aaf5ec97362c6da8136ed0d 100644 (file)
@@ -18,6 +18,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
   alias Pleroma.ReportNote
   alias Pleroma.Tests.ObanHelpers
   alias Pleroma.User
+  alias Pleroma.Web
   alias Pleroma.UserInviteToken
   alias Pleroma.Web.ActivityPub.Relay
   alias Pleroma.Web.CommonAPI
@@ -737,6 +738,39 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
              }
     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
       insert(:user)
 
@@ -3526,7 +3560,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
     end
 
     test "success", %{conn: conn} do
-      base_url = Pleroma.Web.base_url()
+      base_url = Web.base_url()
       app_name = "Trusted app"
 
       response =
@@ -3547,7 +3581,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
     end
 
     test "with trusted", %{conn: conn} do
-      base_url = Pleroma.Web.base_url()
+      base_url = Web.base_url()
       app_name = "Trusted app"
 
       response =