Merge branch '2301-users-search-discoverability-fix' into 'develop'

[#2301] Proper handling of User.is_discoverable

Closes #2301

See merge request pleroma/pleroma!3162
This commit is contained in:
feld 2020-11-19 20:33:52 +00:00
commit 79a509ee61
13 changed files with 18 additions and 65 deletions

View File

@ -35,7 +35,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Fixed ### Fixed
- <details> - Users with `is_discoverable` field set to false (default value) will appear in in-service search results but be hidden from external services (search bots etc.).
<details>
<summary>API Changes</summary> <summary>API Changes</summary>
- Mastodon API: Current user is now included in conversation if it's the only participant. - Mastodon API: Current user is now included in conversation if it's the only participant.
- Mastodon API: Fixed last_status.account being not filled with account data. - Mastodon API: Fixed last_status.account being not filled with account data.
@ -71,7 +73,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Renamed `:await_up_timeout` in `:connections_pool` namespace to `:connect_timeout`, old name is deprecated. - Renamed `:await_up_timeout` in `:connections_pool` namespace to `:connect_timeout`, old name is deprecated.
- Renamed `:timeout` in `pools` namespace to `:recv_timeout`, old name is deprecated. - Renamed `:timeout` in `pools` namespace to `:recv_timeout`, old name is deprecated.
- The `discoverable` field in the `User` struct will now add a NOINDEX metatag to profile pages when false. - The `discoverable` field in the `User` struct will now add a NOINDEX metatag to profile pages when false.
- Users with the `discoverable` field set to false will not show up in searches. - Users with the `is_discoverable` field set to false will not show up in searches ([bug](https://git.pleroma.social/pleroma/pleroma/-/issues/2301)).
- Minimum lifetime for ephmeral activities changed to 10 minutes and made configurable (`:min_lifetime` option). - Minimum lifetime for ephmeral activities changed to 10 minutes and made configurable (`:min_lifetime` option).
- Introduced optional dependencies on `ffmpeg`, `ImageMagick`, `exiftool` software packages. Please refer to `docs/installation/optional/media_graphics_packages.md`. - Introduced optional dependencies on `ffmpeg`, `ImageMagick`, `exiftool` software packages. Please refer to `docs/installation/optional/media_graphics_packages.md`.
- <details> - <details>

View File

@ -554,7 +554,7 @@ Response:
* `show_role` * `show_role`
* `skip_thread_containment` * `skip_thread_containment`
* `fields` * `fields`
* `discoverable` * `is_discoverable`
* `actor_type` * `actor_type`
* Responses: * Responses:

View File

@ -84,7 +84,7 @@ Has these additional fields under the `pleroma` object:
- `show_role`: boolean, nullable, true when the user wants his role (e.g admin, moderator) to be shown - `show_role`: boolean, nullable, true when the user wants his role (e.g admin, moderator) to be shown
- `no_rich_text` - boolean, nullable, true when html tags are stripped from all statuses requested from the API - `no_rich_text` - boolean, nullable, true when html tags are stripped from all statuses requested from the API
- `discoverable`: boolean, true when the user allows discovery of the account in search results and other services. - `discoverable`: boolean, true when the user allows external services (search bots) etc. to index / list the account (regardless of this setting, user will still appear in regular search results)
- `actor_type`: string, the type of this account. - `actor_type`: string, the type of this account.
## Conversations ## Conversations
@ -207,7 +207,7 @@ Additional parameters can be added to the JSON body/Form data:
- `skip_thread_containment` - if true, skip filtering out broken threads - `skip_thread_containment` - if true, skip filtering out broken threads
- `allow_following_move` - if true, allows automatically follow moved following accounts - `allow_following_move` - if true, allows automatically follow moved following accounts
- `pleroma_background_image` - sets the background image of the user. Can be set to "" (an empty string) to reset. - `pleroma_background_image` - sets the background image of the user. Can be set to "" (an empty string) to reset.
- `discoverable` - if true, discovery of this account in search results and other services is allowed. - `discoverable` - if true, external services (search bots) etc. are allowed to index / list the account (regardless of this setting, user will still appear in regular search results).
- `actor_type` - the type of this account. - `actor_type` - the type of this account.
- `accepts_chat_messages` - if false, this account will reject all chat messages. - `accepts_chat_messages` - if false, this account will reject all chat messages.

View File

@ -85,7 +85,6 @@ defp search_query(query_string, for_user, following, top_user_ids) do
|> base_query(following) |> base_query(following)
|> filter_blocked_user(for_user) |> filter_blocked_user(for_user)
|> filter_invisible_users() |> filter_invisible_users()
|> filter_discoverable_users()
|> filter_internal_users() |> filter_internal_users()
|> filter_blocked_domains(for_user) |> filter_blocked_domains(for_user)
|> fts_search(query_string) |> fts_search(query_string)
@ -163,10 +162,6 @@ defp filter_invisible_users(query) do
from(q in query, where: q.invisible == false) from(q in query, where: q.invisible == false)
end end
defp filter_discoverable_users(query) do
from(q in query, where: q.is_discoverable == true)
end
defp filter_internal_users(query) do defp filter_internal_users(query) do
from(q in query, where: q.actor_type != "Application") from(q in query, where: q.actor_type != "Application")
end end

View File

@ -110,6 +110,7 @@ def render("user.json", %{user: user}) do
"endpoints" => endpoints, "endpoints" => endpoints,
"attachment" => fields, "attachment" => fields,
"tag" => emoji_tags, "tag" => emoji_tags,
# Note: key name is indeed "discoverable" (not an error)
"discoverable" => user.is_discoverable, "discoverable" => user.is_discoverable,
"capabilities" => capabilities "capabilities" => capabilities
} }

View File

@ -624,7 +624,7 @@ defp update_credentials_request do
allOf: [BooleanLike], allOf: [BooleanLike],
nullable: true, nullable: true,
description: description:
"Discovery of this account in search results and other services is allowed." "Discovery (listing, indexing) of this account by external services (search bots etc.) is allowed."
}, },
actor_type: ActorType actor_type: ActorType
}, },

View File

@ -127,7 +127,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Account do
discoverable: %Schema{ discoverable: %Schema{
type: :boolean, type: :boolean,
description: description:
"whether the user allows discovery of the account in search results and other services." "whether the user allows indexing / listing of the account by external services (search engines etc.)."
}, },
no_rich_text: %Schema{ no_rich_text: %Schema{
type: :boolean, type: :boolean,

View File

@ -208,7 +208,9 @@ def update_credentials(%{assigns: %{user: user}, body_params: params} = conn, _p
if bot, do: {:ok, "Service"}, else: {:ok, "Person"} if bot, do: {:ok, "Service"}, else: {:ok, "Person"}
end) end)
|> Maps.put_if_present(:actor_type, params[:actor_type]) |> Maps.put_if_present(:actor_type, params[:actor_type])
# Note: param name is indeed :locked (not an error)
|> Maps.put_if_present(:is_locked, params[:locked]) |> Maps.put_if_present(:is_locked, params[:locked])
# Note: param name is indeed :discoverable (not an error)
|> Maps.put_if_present(:is_discoverable, params[:discoverable]) |> Maps.put_if_present(:is_discoverable, params[:discoverable])
# What happens here: # What happens here:

View File

@ -6,7 +6,7 @@ defmodule Pleroma.Web.Metadata.Providers.RestrictIndexing do
@behaviour Pleroma.Web.Metadata.Providers.Provider @behaviour Pleroma.Web.Metadata.Providers.Provider
@moduledoc """ @moduledoc """
Restricts indexing of remote users. Restricts indexing of remote and/or non-discoverable users.
""" """
@impl true @impl true

View File

@ -65,12 +65,13 @@ test "excludes invisible users from results" do
assert found_user.id == user.id assert found_user.id == user.id
end end
test "excludes users when discoverable is false" do # Note: as in Mastodon, `is_discoverable` doesn't anyhow relate to user searchability
test "includes non-discoverable users in results" do
insert(:user, %{nickname: "john 3000", is_discoverable: false}) insert(:user, %{nickname: "john 3000", is_discoverable: false})
insert(:user, %{nickname: "john 3001"}) insert(:user, %{nickname: "john 3001"})
users = User.search("john") users = User.search("john")
assert Enum.count(users) == 1 assert Enum.count(users) == 2
end end
test "excludes service actors from results" do test "excludes service actors from results" do

View File

@ -203,6 +203,7 @@ test "it returns unconfirmed user" do
assert count == 1 assert count == 1
end end
# Note: as in Mastodon, `is_discoverable` doesn't anyhow relate to user searchability
test "it returns non-discoverable users" do test "it returns non-discoverable users" do
insert(:user) insert(:user)
insert(:user, is_discoverable: false) insert(:user, is_discoverable: false)

View File

@ -18,7 +18,7 @@ test "for local user" do
}) == [] }) == []
end end
test "for local user when discoverable is false" do test "for local user when `is_discoverable` is false" do
assert Pleroma.Web.Metadata.Providers.RestrictIndexing.build_tags(%{ assert Pleroma.Web.Metadata.Providers.RestrictIndexing.build_tags(%{
user: %Pleroma.User{local: true, is_discoverable: false} user: %Pleroma.User{local: true, is_discoverable: false}
}) == [{:meta, [name: "robots", content: "noindex, noarchive"], []}] }) == [{:meta, [name: "robots", content: "noindex, noarchive"], []}]

View File

@ -1,49 +0,0 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MetadataTest do
use Pleroma.DataCase, async: true
import Pleroma.Factory
describe "restrict indexing remote users" do
test "for remote user" do
user = insert(:user, local: false)
assert Pleroma.Web.Metadata.build_tags(%{user: user}) =~
"<meta content=\"noindex, noarchive\" name=\"robots\">"
end
test "for local user" do
user = insert(:user, is_discoverable: false)
assert Pleroma.Web.Metadata.build_tags(%{user: user}) =~
"<meta content=\"noindex, noarchive\" name=\"robots\">"
end
test "for local user set to discoverable" do
user = insert(:user, is_discoverable: true)
refute Pleroma.Web.Metadata.build_tags(%{user: user}) =~
"<meta content=\"noindex, noarchive\" name=\"robots\">"
end
end
describe "no metadata for private instances" do
test "for local user set to discoverable" do
clear_config([:instance, :public], false)
user = insert(:user, bio: "This is my secret fedi account bio", is_discoverable: true)
assert "" = Pleroma.Web.Metadata.build_tags(%{user: user})
end
test "search exclusion metadata is included" do
clear_config([:instance, :public], false)
user = insert(:user, bio: "This is my secret fedi account bio", is_discoverable: false)
assert ~s(<meta content="noindex, noarchive" name="robots">) ==
Pleroma.Web.Metadata.build_tags(%{user: user})
end
end
end