[#2301] Proper handling of User.is_discoverable
: users appear in in-service search but are hidden from external services like search bots.
This commit is contained in:
parent
fcad3e716a
commit
e164c37139
|
@ -34,6 +34,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
- 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>
|
<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.
|
||||||
|
@ -70,7 +72,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>
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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_non_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,12 +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_non_discoverable_users(query) do
|
|
||||||
# Note: commented out — can't do it with users being non-discoverable by default
|
|
||||||
# from(q in query, where: q.is_discoverable == true)
|
|
||||||
query
|
|
||||||
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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
},
|
},
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -65,8 +65,8 @@ test "excludes invisible users from results" do
|
||||||
assert found_user.id == user.id
|
assert found_user.id == user.id
|
||||||
end
|
end
|
||||||
|
|
||||||
# NOTE: as long as users are non-discoverable by default, we can't filter out most users: #2301
|
# Note: as in Mastodon, `is_discoverable` doesn't anyhow relate to user searchability
|
||||||
test "does NOT exclude non-discoverable users from results (as long as it's the default)" do
|
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"})
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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"], []}]
|
||||||
|
|
|
@ -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
|
|
Loading…
Reference in a new issue