Add "local" params to users search
authorMaxim Filippov <colixer@gmail.com>
Fri, 1 Mar 2019 17:13:02 +0000 (20:13 +0300)
committerMaxim Filippov <colixer@gmail.com>
Fri, 1 Mar 2019 17:13:02 +0000 (20:13 +0300)
docs/Admin-API.md
lib/pleroma/user.ex
lib/pleroma/web/admin_api/admin_api_controller.ex
lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
lib/pleroma/web/twitter_api/twitter_api_controller.ex
test/web/admin_api/admin_api_controller_test.exs

index ed19bc875d698d47a1eb3044bb8f86f561e0ac00..4403620bf6d977daa88cc3d2077ba8408e40b4b6 100644 (file)
@@ -20,13 +20,14 @@ Authentication is required and the user must be an admin.
 ]
 ```
 
-## `/api/pleroma/admin/users/search?query={query}`
+## `/api/pleroma/admin/users/search?query={query}&local={local}`
 
-### Search users
+### Search users by name or nickname
 
 - Method `GET`
 - Params:
-  - `query`
+  - `query`: **string** search term
+  - `local`: **bool** whether to return only local users
 - Response:
 
 ```JSON
index 52df171c55ea2933f79e0fd2160983de8072a12d..af3ce705d9c307d0a7661bc20b9c66c5415e310b 100644 (file)
@@ -755,18 +755,25 @@ defmodule Pleroma.User do
     Repo.all(query)
   end
 
-  def search(query, resolve \\ false, for_user \\ nil, limit \\ 20) do
+  def search(term, options \\ %{}) do
     # Strip the beginning @ off if there is a query
-    query = String.trim_leading(query, "@")
+    term = String.trim_leading(term, "@")
+    query = options[:query] || User
 
-    if resolve, do: get_or_fetch(query)
+    if options[:resolve], do: get_or_fetch(term)
 
-    fts_results = do_search(fts_search_subquery(query), for_user, %{limit: limit})
+    fts_results =
+      do_search(fts_search_subquery(term, query), options[:for_user], %{
+        limit: options[:limit]
+      })
 
     {:ok, trigram_results} =
       Repo.transaction(fn ->
         Ecto.Adapters.SQL.query(Repo, "select set_limit(0.25)", [])
-        do_search(trigram_search_subquery(query), for_user, %{limit: limit})
+
+        do_search(trigram_search_subquery(term, query), options[:for_user], %{
+          limit: options[:limit]
+        })
       end)
 
     Enum.uniq_by(fts_results ++ trigram_results, & &1.id)
@@ -809,9 +816,9 @@ defmodule Pleroma.User do
     boost_search_results(results, for_user)
   end
 
-  defp fts_search_subquery(query) do
+  defp fts_search_subquery(term, query) do
     processed_query =
-      query
+      term
       |> String.replace(~r/\W+/, " ")
       |> String.trim()
       |> String.split()
@@ -819,7 +826,7 @@ defmodule Pleroma.User do
       |> Enum.join(" | ")
 
     from(
-      u in User,
+      u in query,
       select_merge: %{
         search_rank:
           fragment(
@@ -849,19 +856,19 @@ defmodule Pleroma.User do
     )
   end
 
-  defp trigram_search_subquery(query) do
+  defp trigram_search_subquery(term, query) do
     from(
-      u in User,
+      u in query,
       select_merge: %{
         search_rank:
           fragment(
             "similarity(?, trim(? || ' ' || coalesce(?, '')))",
-            ^query,
+            ^term,
             u.nickname,
             u.name
           )
       },
-      where: fragment("trim(? || ' ' || coalesce(?, '')) % ?", u.nickname, u.name, ^query)
+      where: fragment("trim(? || ' ' || coalesce(?, '')) % ?", u.nickname, u.name, ^term)
     )
   end
 
@@ -1018,6 +1025,14 @@ defmodule Pleroma.User do
     update_and_set_cache(cng)
   end
 
+  def maybe_local_user_query(local) when local == true do
+    local_user_query()
+  end
+
+  def maybe_local_user_query(local) when local == false do
+    User
+  end
+
   def local_user_query do
     from(
       u in User,
index 37159cd4017a84185f5032e864a1b3c0e79a62af..a8f9e5012a652adbf18ef112b4ab669ed16fd023 100644 (file)
@@ -78,8 +78,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
            )
   end
 
-  def search_users(%{assigns: %{user: admin}} = conn, %{"query" => query}) do
-    users = User.search(query, true, admin, @users_page_size)
+  def search_users(%{assigns: %{user: admin}} = conn, %{"query" => term} = params) do
+    users =
+      User.search(term,
+        query: User.maybe_local_user_query(params["local"] == "true"),
+        resolve: true,
+        for_user: admin,
+        limit: @users_page_size
+      )
 
     conn
     |> json(
index 12987442a0c487f1695d961d184643f506e1da94..056be49b08e3f29751c4c95affcc6ecc8db4c104 100644 (file)
@@ -894,7 +894,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
   end
 
   def search2(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
-    accounts = User.search(query, params["resolve"] == "true", user)
+    accounts = User.search(query, resolve: params["resolve"] == "true", for_user: user)
 
     statuses = status_search(user, query)
 
@@ -919,7 +919,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
   end
 
   def search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
-    accounts = User.search(query, params["resolve"] == "true", user)
+    accounts = User.search(query, resolve: params["resolve"] == "true", for_user: user)
 
     statuses = status_search(user, query)
 
@@ -941,7 +941,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
   end
 
   def account_search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
-    accounts = User.search(query, params["resolve"] == "true", user)
+    accounts = User.search(query, resolve: params["resolve"] == "true", for_user: user)
 
     res = AccountView.render("accounts.json", users: accounts, for: user, as: :user)
 
index 0d74c30c36266b92b545b02c2d8e46d47d35133c..19264a93f37ad78b61c90449ff02c7127f1deb2d 100644 (file)
@@ -702,7 +702,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
   end
 
   def search_user(%{assigns: %{user: user}} = conn, %{"query" => query}) do
-    users = User.search(query, true, user)
+    users = User.search(query, resolve: true, for_user: user)
 
     conn
     |> put_view(UserView)
index 14625af32b71c190bfec84879e9bd2e596cd26e8..460f2a6bd3d89e4393d14a9cb8c94d7d1ca9721c 100644 (file)
@@ -388,25 +388,51 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
              }
   end
 
-  test "GET /api/pleroma/admin/users/search" do
-    admin = insert(:user, info: %{is_admin: true})
-    user = insert(:user, nickname: "bob")
+  describe "GET /api/pleroma/admin/users/search" do
+    test "regular search" do
+      admin = insert(:user, info: %{is_admin: true})
+      user = insert(:user, nickname: "bob")
 
-    conn =
-      build_conn()
-      |> assign(:user, admin)
-      |> get("/api/pleroma/admin/users/search?query=bo")
-
-    assert json_response(conn, 200) == %{
-             "count" => 1,
-             "page_size" => 50,
-             "users" => [
-               %{
-                 "deactivated" => user.info.deactivated,
-                 "id" => user.id,
-                 "nickname" => user.nickname
-               }
-             ]
-           }
+      conn =
+        build_conn()
+        |> assign(:user, admin)
+        |> get("/api/pleroma/admin/users/search?query=bo")
+
+      assert json_response(conn, 200) == %{
+              "count" => 1,
+              "page_size" => 50,
+              "users" => [
+                %{
+                  "deactivated" => user.info.deactivated,
+                  "id" => user.id,
+                  "nickname" => user.nickname
+                }
+              ]
+            }
+    end
+
+    test "only local users" do
+      admin = insert(:user, info: %{is_admin: true})
+      user = insert(:user, nickname: "bob")
+
+      insert(:user, nickname: "bobb", local: false)
+
+      conn =
+        build_conn()
+        |> assign(:user, admin)
+        |> get("/api/pleroma/admin/users/search?query=bo&local=true")
+
+      assert json_response(conn, 200) == %{
+              "count" => 1,
+              "page_size" => 50,
+              "users" => [
+                %{
+                  "deactivated" => user.info.deactivated,
+                  "id" => user.id,
+                  "nickname" => user.nickname
+                }
+              ]
+            }
+    end
   end
 end