commit: a1a25029da74949a79c73d400b6f2bc0bf1dc01a
parent 5996bef7cdbe311443df3a75daf3968aee92eba6
Author: Lain Soykaf <lain@lain.com>
Date: Sun, 12 Nov 2023 16:19:54 +0400
B DatabaseSearch: Fix local-only search.
Diffstat:
3 files changed, 81 insertions(+), 68 deletions(-)
diff --git a/lib/pleroma/search/database_search.ex b/lib/pleroma/search/database_search.ex
@@ -8,6 +8,7 @@ defmodule Pleroma.Search.DatabaseSearch do
alias Pleroma.Pagination
alias Pleroma.User
alias Pleroma.Web.ActivityPub.Visibility
+ alias Pleroma.Config
require Pleroma.Constants
@@ -17,7 +18,7 @@ defmodule Pleroma.Search.DatabaseSearch do
@impl true
def search(user, search_query, options \\ []) do
- index_type = if Pleroma.Config.get([:database, :rum_enabled]), do: :rum, else: :gin
+ index_type = if Config.get([:database, :rum_enabled]), do: :rum, else: :gin
limit = Enum.min([Keyword.get(options, :limit), 40])
offset = Keyword.get(options, :offset, 0)
author = Keyword.get(options, :author)
@@ -33,7 +34,7 @@ defmodule Pleroma.Search.DatabaseSearch do
Activity
|> Activity.with_preloaded_object()
|> Activity.restrict_deactivated_users()
- |> restrict_public()
+ |> restrict_public(user)
|> query_with(index_type, search_query, search_function)
|> maybe_restrict_local(user)
|> maybe_restrict_author(author)
@@ -49,10 +50,10 @@ defmodule Pleroma.Search.DatabaseSearch do
end
@impl true
- def add_to_index(_activity), do: nil
+ def add_to_index(_activity), do: :ok
@impl true
- def remove_from_index(_object), do: nil
+ def remove_from_index(_object), do: :ok
def maybe_restrict_author(query, %User{} = author) do
Activity.Queries.by_author(query, author)
@@ -66,7 +67,19 @@ defmodule Pleroma.Search.DatabaseSearch do
def maybe_restrict_blocked(query, _), do: query
- def restrict_public(q) do
+ defp restrict_public(q, user) when not is_nil(user) do
+ intended_recipients = [
+ Pleroma.Constants.as_public(),
+ Pleroma.Web.ActivityPub.Utils.as_local_public()
+ ]
+
+ from([a, o] in q,
+ where: fragment("?->>'type' = 'Create'", a.data),
+ where: fragment("? && ?", ^intended_recipients, a.recipients)
+ )
+ end
+
+ defp restrict_public(q, _user) do
from([a, o] in q,
where: fragment("?->>'type' = 'Create'", a.data),
where: ^Pleroma.Constants.as_public() in a.recipients
@@ -134,7 +147,7 @@ defmodule Pleroma.Search.DatabaseSearch do
end
def maybe_restrict_local(q, user) do
- limit = Pleroma.Config.get([:instance, :limit_to_local_content], :unauthenticated)
+ limit = Config.get([:instance, :limit_to_local_content], :unauthenticated)
case {limit, user} do
{:all, _} -> restrict_local(q)
diff --git a/test/pleroma/search/database_search_test.ex b/test/pleroma/search/database_search_test.ex
@@ -1,62 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Search.DatabaseSearchTest do
- alias Pleroma.Search.DatabaseSearch
- alias Pleroma.Web.CommonAPI
- import Pleroma.Factory
-
- use Pleroma.DataCase, async: true
-
- test "it finds something" do
- user = insert(:user)
- {:ok, post} = CommonAPI.post(user, %{status: "it's wednesday my dudes"})
-
- [result] = DatabaseSearch.search(nil, "wednesday")
-
- assert result.id == post.id
- end
-
- test "it finds local-only posts for authenticated users" do
- user = insert(:user)
- reader = insert(:user)
- {:ok, post} = CommonAPI.post(user, %{status: "it's wednesday my dudes", visibility: "local"})
-
- [result] = Search.search(reader, "wednesday")
-
- assert result.id == post.id
- end
-
- test "it does not find local-only posts for anonymous users" do
- user = insert(:user)
- {:ok, _post} = CommonAPI.post(user, %{status: "it's wednesday my dudes", visibility: "local"})
-
- assert [] = Search.search(nil, "wednesday")
- end
-
- test "using plainto_tsquery on postgres < 11" do
- old_version = :persistent_term.get({Pleroma.Repo, :postgres_version})
- :persistent_term.put({Pleroma.Repo, :postgres_version}, 10.0)
- on_exit(fn -> :persistent_term.put({Pleroma.Repo, :postgres_version}, old_version) end)
-
- user = insert(:user)
- {:ok, post} = CommonAPI.post(user, %{status: "it's wednesday my dudes"})
- {:ok, _post2} = CommonAPI.post(user, %{status: "it's wednesday my bros"})
-
- # plainto doesn't understand complex queries
- assert [result] = DatabaseSearch.search(nil, "wednesday -dudes")
-
- assert result.id == post.id
- end
-
- test "using websearch_to_tsquery" do
- user = insert(:user)
- {:ok, _post} = CommonAPI.post(user, %{status: "it's wednesday my dudes"})
- {:ok, other_post} = CommonAPI.post(user, %{status: "it's wednesday my bros"})
-
- assert [result] = DatabaseSearch.search(nil, "wednesday -dudes")
-
- assert result.id == other_post.id
- end
-end
diff --git a/test/pleroma/search/database_search_test.exs b/test/pleroma/search/database_search_test.exs
@@ -0,0 +1,62 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Search.DatabaseSearchTest do
+ alias Pleroma.Search.DatabaseSearch, as: Search
+ alias Pleroma.Web.CommonAPI
+ import Pleroma.Factory
+
+ use Pleroma.DataCase, async: true
+
+ test "it finds something" do
+ user = insert(:user)
+ {:ok, post} = CommonAPI.post(user, %{status: "it's wednesday my dudes"})
+
+ [result] = Search.search(nil, "wednesday")
+
+ assert result.id == post.id
+ end
+
+ test "it finds local-only posts for authenticated users" do
+ user = insert(:user)
+ reader = insert(:user)
+ {:ok, post} = CommonAPI.post(user, %{status: "it's wednesday my dudes", visibility: "local"})
+
+ [result] = Search.search(reader, "wednesday")
+
+ assert result.id == post.id
+ end
+
+ test "it does not find local-only posts for anonymous users" do
+ user = insert(:user)
+ {:ok, _post} = CommonAPI.post(user, %{status: "it's wednesday my dudes", visibility: "local"})
+
+ assert [] = Search.search(nil, "wednesday")
+ end
+
+ test "using plainto_tsquery on postgres < 11" do
+ old_version = :persistent_term.get({Pleroma.Repo, :postgres_version})
+ :persistent_term.put({Pleroma.Repo, :postgres_version}, 10.0)
+ on_exit(fn -> :persistent_term.put({Pleroma.Repo, :postgres_version}, old_version) end)
+
+ user = insert(:user)
+ {:ok, post} = CommonAPI.post(user, %{status: "it's wednesday my dudes"})
+ {:ok, _post2} = CommonAPI.post(user, %{status: "it's wednesday my bros"})
+
+ # plainto doesn't understand complex queries
+ assert [result] = Search.search(nil, "wednesday -dudes")
+
+ assert result.id == post.id
+ end
+
+ test "using websearch_to_tsquery" do
+ user = insert(:user)
+ {:ok, _post} = CommonAPI.post(user, %{status: "it's wednesday my dudes"})
+ {:ok, other_post} = CommonAPI.post(user, %{status: "it's wednesday my bros"})
+
+ assert [result] = Search.search(nil, "wednesday -dudes")
+
+ assert result.id == other_post.id
+ end
+end