forked from AkkomaGang/akkoma
Add "local" params to users search
This commit is contained in:
parent
adac745512
commit
5b08b470f6
6 changed files with 87 additions and 39 deletions
|
@ -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`
|
- Method `GET`
|
||||||
- Params:
|
- Params:
|
||||||
- `query`
|
- `query`: **string** search term
|
||||||
|
- `local`: **bool** whether to return only local users
|
||||||
- Response:
|
- Response:
|
||||||
|
|
||||||
```JSON
|
```JSON
|
||||||
|
|
|
@ -755,18 +755,25 @@ def get_recipients_from_activity(%Activity{recipients: to}) do
|
||||||
Repo.all(query)
|
Repo.all(query)
|
||||||
end
|
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
|
# 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} =
|
{:ok, trigram_results} =
|
||||||
Repo.transaction(fn ->
|
Repo.transaction(fn ->
|
||||||
Ecto.Adapters.SQL.query(Repo, "select set_limit(0.25)", [])
|
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)
|
end)
|
||||||
|
|
||||||
Enum.uniq_by(fts_results ++ trigram_results, & &1.id)
|
Enum.uniq_by(fts_results ++ trigram_results, & &1.id)
|
||||||
|
@ -809,9 +816,9 @@ defp do_search(subquery, for_user, options) do
|
||||||
boost_search_results(results, for_user)
|
boost_search_results(results, for_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp fts_search_subquery(query) do
|
defp fts_search_subquery(term, query) do
|
||||||
processed_query =
|
processed_query =
|
||||||
query
|
term
|
||||||
|> String.replace(~r/\W+/, " ")
|
|> String.replace(~r/\W+/, " ")
|
||||||
|> String.trim()
|
|> String.trim()
|
||||||
|> String.split()
|
|> String.split()
|
||||||
|
@ -819,7 +826,7 @@ defp fts_search_subquery(query) do
|
||||||
|> Enum.join(" | ")
|
|> Enum.join(" | ")
|
||||||
|
|
||||||
from(
|
from(
|
||||||
u in User,
|
u in query,
|
||||||
select_merge: %{
|
select_merge: %{
|
||||||
search_rank:
|
search_rank:
|
||||||
fragment(
|
fragment(
|
||||||
|
@ -849,19 +856,19 @@ defp fts_search_subquery(query) do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp trigram_search_subquery(query) do
|
defp trigram_search_subquery(term, query) do
|
||||||
from(
|
from(
|
||||||
u in User,
|
u in query,
|
||||||
select_merge: %{
|
select_merge: %{
|
||||||
search_rank:
|
search_rank:
|
||||||
fragment(
|
fragment(
|
||||||
"similarity(?, trim(? || ' ' || coalesce(?, '')))",
|
"similarity(?, trim(? || ' ' || coalesce(?, '')))",
|
||||||
^query,
|
^term,
|
||||||
u.nickname,
|
u.nickname,
|
||||||
u.name
|
u.name
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
where: fragment("trim(? || ' ' || coalesce(?, '')) % ?", u.nickname, u.name, ^query)
|
where: fragment("trim(? || ' ' || coalesce(?, '')) % ?", u.nickname, u.name, ^term)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1018,6 +1025,14 @@ def unblock_domain(user, domain) do
|
||||||
update_and_set_cache(cng)
|
update_and_set_cache(cng)
|
||||||
end
|
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
|
def local_user_query do
|
||||||
from(
|
from(
|
||||||
u in User,
|
u in User,
|
||||||
|
|
|
@ -78,8 +78,14 @@ def list_users(%{assigns: %{user: admin}} = conn, %{"page" => page_string}) do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def search_users(%{assigns: %{user: admin}} = conn, %{"query" => query}) do
|
def search_users(%{assigns: %{user: admin}} = conn, %{"query" => term} = params) do
|
||||||
users = User.search(query, true, admin, @users_page_size)
|
users =
|
||||||
|
User.search(term,
|
||||||
|
query: User.maybe_local_user_query(params["local"] == "true"),
|
||||||
|
resolve: true,
|
||||||
|
for_user: admin,
|
||||||
|
limit: @users_page_size
|
||||||
|
)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> json(
|
|> json(
|
||||||
|
|
|
@ -894,7 +894,7 @@ def status_search(user, query) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def search2(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
|
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)
|
statuses = status_search(user, query)
|
||||||
|
|
||||||
|
@ -919,7 +919,7 @@ def search2(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
|
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)
|
statuses = status_search(user, query)
|
||||||
|
|
||||||
|
@ -941,7 +941,7 @@ def search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def account_search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
|
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)
|
res = AccountView.render("accounts.json", users: accounts, for: user, as: :user)
|
||||||
|
|
||||||
|
|
|
@ -702,7 +702,7 @@ def search(%{assigns: %{user: user}} = conn, %{"q" => _query} = params) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def search_user(%{assigns: %{user: user}} = conn, %{"query" => query}) do
|
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
|
conn
|
||||||
|> put_view(UserView)
|
|> put_view(UserView)
|
||||||
|
|
|
@ -388,25 +388,51 @@ test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation" do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "GET /api/pleroma/admin/users/search" do
|
describe "GET /api/pleroma/admin/users/search" do
|
||||||
admin = insert(:user, info: %{is_admin: true})
|
test "regular search" do
|
||||||
user = insert(:user, nickname: "bob")
|
admin = insert(:user, info: %{is_admin: true})
|
||||||
|
user = insert(:user, nickname: "bob")
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
build_conn()
|
build_conn()
|
||||||
|> assign(:user, admin)
|
|> assign(:user, admin)
|
||||||
|> get("/api/pleroma/admin/users/search?query=bo")
|
|> get("/api/pleroma/admin/users/search?query=bo")
|
||||||
|
|
||||||
assert json_response(conn, 200) == %{
|
assert json_response(conn, 200) == %{
|
||||||
"count" => 1,
|
"count" => 1,
|
||||||
"page_size" => 50,
|
"page_size" => 50,
|
||||||
"users" => [
|
"users" => [
|
||||||
%{
|
%{
|
||||||
"deactivated" => user.info.deactivated,
|
"deactivated" => user.info.deactivated,
|
||||||
"id" => user.id,
|
"id" => user.id,
|
||||||
"nickname" => user.nickname
|
"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
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue