summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md12
-rw-r--r--config/config.exs3
-rw-r--r--docs/API/admin_api.md2
-rw-r--r--docs/API/differences_in_mastoapi_responses.md4
-rw-r--r--docs/configuration/cheatsheet.md1
-rw-r--r--lib/mix/pleroma.ex1
-rw-r--r--lib/pleroma/activity/search.ex5
-rw-r--r--lib/pleroma/application.ex7
-rw-r--r--lib/pleroma/password_reset_token.ex11
-rw-r--r--lib/pleroma/user.ex27
-rw-r--r--lib/pleroma/user/search.ex5
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex4
-rw-r--r--lib/pleroma/web/activity_pub/mrf/media_proxy_warming_policy.ex19
-rw-r--r--lib/pleroma/web/activity_pub/side_effects.ex5
-rw-r--r--lib/pleroma/web/activity_pub/views/user_view.ex1
-rw-r--r--lib/pleroma/web/api_spec/operations/account_operation.ex8
-rw-r--r--lib/pleroma/web/api_spec/operations/emoji_reaction_operation.ex6
-rw-r--r--lib/pleroma/web/api_spec/operations/status_operation.ex16
-rw-r--r--lib/pleroma/web/api_spec/schemas/account.ex2
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/account_controller.ex5
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/status_controller.ex10
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex12
-rw-r--r--lib/pleroma/web/mastodon_api/views/status_view.ex26
-rw-r--r--lib/pleroma/web/metadata/providers/restrict_indexing.ex2
-rw-r--r--lib/pleroma/web/pleroma_api/controllers/chat_controller.ex4
-rw-r--r--lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex32
-rw-r--r--lib/pleroma/web/pleroma_api/views/emoji_reaction_view.ex2
-rw-r--r--lib/pleroma/web/rich_media/helpers.ex5
-rw-r--r--lib/pleroma/web/twitter_api/controllers/password_controller.ex1
-rw-r--r--lib/pleroma/workers/background_worker.ex15
-rw-r--r--priv/repo/migrations/20200915095704_remove_background_jobs.exs22
-rw-r--r--test/pleroma/config/deprecation_warnings_test.exs2
-rw-r--r--test/pleroma/user_search_test.exs5
-rw-r--r--test/pleroma/web/activity_pub/mrf/media_proxy_warming_policy_test.exs12
-rw-r--r--test/pleroma/web/admin_api/search_test.exs1
-rw-r--r--test/pleroma/web/mastodon_api/controllers/account_controller_test.exs33
-rw-r--r--test/pleroma/web/mastodon_api/controllers/status_controller_test.exs77
-rw-r--r--test/pleroma/web/mastodon_api/controllers/timeline_controller_test.exs158
-rw-r--r--test/pleroma/web/mastodon_api/views/status_view_test.exs44
-rw-r--r--test/pleroma/web/metadata/providers/restrict_indexing_test.exs2
-rw-r--r--test/pleroma/web/metadata_test.exs49
-rw-r--r--test/pleroma/web/pleroma_api/controllers/emoji_reaction_controller_test.exs42
-rw-r--r--test/pleroma/web/pleroma_api/views/chat_message_reference_view_test.exs2
-rw-r--r--test/pleroma/web/twitter_api/password_controller_test.exs39
44 files changed, 601 insertions, 140 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5e09df22c..281f06729 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -21,6 +21,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Configuration: Add `:instance, autofollowing_nicknames` setting to provide a way to make accounts automatically follow new users that register on the local Pleroma instance.
- Ability to view remote timelines, with ex. `/api/v1/timelines/public?instance=lain.com` and streams `public:remote` and `public:remote:media`.
- The site title is now injected as a `title` tag like preloads or metadata.
+- Password reset tokens now are not accepted after a certain age.
<details>
<summary>API Changes</summary>
@@ -34,11 +35,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### 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>
<summary>API Changes</summary>
-- 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: 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.
</details>
## Unreleased (Patch)
@@ -48,7 +50,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Fixed
- Config generation: rename `Pleroma.Upload.Filter.ExifTool` to `Pleroma.Upload.Filter.Exiftool`.
+- Search: RUM index search speed has been fixed.
- S3 Uploads with Elixir 1.11.
+- Emoji Reaction activity filtering from blocked and muted accounts.
- Mix task pleroma.user delete_activities for source installations.
- Fix ability to update Pleroma Chat push notifications with PUT /api/v1/push/subscription and alert type pleroma:chat_mention
- Forwarded reports duplication from Pleroma instances.
@@ -75,7 +79,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 `: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.
-- 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).
- Introduced optional dependencies on `ffmpeg`, `ImageMagick`, `exiftool` software packages. Please refer to `docs/installation/optional/media_graphics_packages.md`.
- <details>
diff --git a/config/config.exs b/config/config.exs
index 1ac140ed0..be5257663 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -263,7 +263,8 @@ config :pleroma, :instance,
length: 16
]
],
- show_reactions: true
+ show_reactions: true,
+ password_reset_token_validity: 60 * 60 * 24
config :pleroma, :welcome,
direct_message: [
diff --git a/docs/API/admin_api.md b/docs/API/admin_api.md
index 19ac6a65f..266f8cef8 100644
--- a/docs/API/admin_api.md
+++ b/docs/API/admin_api.md
@@ -554,7 +554,7 @@ Response:
* `show_role`
* `skip_thread_containment`
* `fields`
- * `discoverable`
+ * `is_discoverable`
* `actor_type`
* Responses:
diff --git a/docs/API/differences_in_mastoapi_responses.md b/docs/API/differences_in_mastoapi_responses.md
index 843496482..6b0ad85d1 100644
--- a/docs/API/differences_in_mastoapi_responses.md
+++ b/docs/API/differences_in_mastoapi_responses.md
@@ -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
- `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.
## 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
- `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.
-- `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.
- `accepts_chat_messages` - if false, this account will reject all chat messages.
diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md
index 4d18ac30a..85551362c 100644
--- a/docs/configuration/cheatsheet.md
+++ b/docs/configuration/cheatsheet.md
@@ -63,6 +63,7 @@ To add configuration to your config file, you can copy it from the base config.
* `external_user_synchronization`: Enabling following/followers counters synchronization for external users.
* `cleanup_attachments`: Remove attachments along with statuses. Does not affect duplicate files and attachments without status. Enabling this will increase load to database when deleting statuses on larger instances.
* `show_reactions`: Let favourites and emoji reactions be viewed through the API (default: `true`).
+* `password_reset_token_validity`: The time after which reset tokens aren't accepted anymore, in seconds (default: one day).
## Welcome
* `direct_message`: - welcome message sent as a direct message.
diff --git a/lib/mix/pleroma.ex b/lib/mix/pleroma.ex
index 3de11efce..6df1cf538 100644
--- a/lib/mix/pleroma.ex
+++ b/lib/mix/pleroma.ex
@@ -19,6 +19,7 @@ defmodule Mix.Pleroma do
def start_pleroma do
Pleroma.Config.Holder.save_default()
Pleroma.Config.Oban.warn()
+ Pleroma.Application.limiters_setup()
Application.put_env(:phoenix, :serve_endpoints, false, persistent: true)
if Pleroma.Config.get(:env) != :test do
diff --git a/lib/pleroma/activity/search.ex b/lib/pleroma/activity/search.ex
index ceb365bb3..382c81118 100644
--- a/lib/pleroma/activity/search.ex
+++ b/lib/pleroma/activity/search.ex
@@ -27,7 +27,10 @@ defmodule Pleroma.Activity.Search do
|> maybe_restrict_local(user)
|> maybe_restrict_author(author)
|> maybe_restrict_blocked(user)
- |> Pagination.fetch_paginated(%{"offset" => offset, "limit" => limit}, :offset)
+ |> Pagination.fetch_paginated(
+ %{"offset" => offset, "limit" => limit, "skip_order" => index_type == :rum},
+ :offset
+ )
|> maybe_fetch(user, search_query)
end
diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex
index 8f08a6222..ced14f87f 100644
--- a/lib/pleroma/application.ex
+++ b/lib/pleroma/application.ex
@@ -57,6 +57,7 @@ defmodule Pleroma.Application do
setup_instrumenters()
load_custom_modules()
Pleroma.Docs.JSON.compile()
+ limiters_setup()
adapter = Application.get_env(:tesla, :adapter)
@@ -272,4 +273,10 @@ defmodule Pleroma.Application do
end
defp http_children(_, _), do: []
+
+ @spec limiters_setup() :: :ok
+ def limiters_setup do
+ [Pleroma.Web.RichMedia.Helpers, Pleroma.Web.MediaProxy]
+ |> Enum.each(&ConcurrentLimiter.new(&1, 1, 0))
+ end
end
diff --git a/lib/pleroma/password_reset_token.ex b/lib/pleroma/password_reset_token.ex
index 787bd4781..fea5b1c22 100644
--- a/lib/pleroma/password_reset_token.ex
+++ b/lib/pleroma/password_reset_token.ex
@@ -40,6 +40,7 @@ defmodule Pleroma.PasswordResetToken do
@spec reset_password(binary(), map()) :: {:ok, User.t()} | {:error, binary()}
def reset_password(token, data) do
with %{used: false} = token <- Repo.get_by(PasswordResetToken, %{token: token}),
+ false <- expired?(token),
%User{} = user <- User.get_cached_by_id(token.user_id),
{:ok, _user} <- User.reset_password(user, data),
{:ok, token} <- Repo.update(used_changeset(token)) do
@@ -48,4 +49,14 @@ defmodule Pleroma.PasswordResetToken do
_e -> {:error, token}
end
end
+
+ def expired?(%__MODULE__{inserted_at: inserted_at}) do
+ validity = Pleroma.Config.get([:instance, :password_reset_token_validity], 0)
+
+ now = NaiveDateTime.utc_now()
+
+ difference = NaiveDateTime.diff(now, inserted_at)
+
+ difference > validity
+ end
end
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index a240579f3..bcd5256c8 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -245,6 +245,18 @@ defmodule Pleroma.User do
end
end
+ def cached_blocked_users_ap_ids(user) do
+ Cachex.fetch!(:user_cache, "blocked_users_ap_ids:#{user.ap_id}", fn _ ->
+ blocked_users_ap_ids(user)
+ end)
+ end
+
+ def cached_muted_users_ap_ids(user) do
+ Cachex.fetch!(:user_cache, "muted_users_ap_ids:#{user.ap_id}", fn _ ->
+ muted_users_ap_ids(user)
+ end)
+ end
+
defdelegate following_count(user), to: FollowingRelationship
defdelegate following(user), to: FollowingRelationship
defdelegate following?(follower, followed), to: FollowingRelationship
@@ -1036,6 +1048,8 @@ defmodule Pleroma.User do
Cachex.del(:user_cache, "ap_id:#{user.ap_id}")
Cachex.del(:user_cache, "nickname:#{user.nickname}")
Cachex.del(:user_cache, "friends_ap_ids:#{user.ap_id}")
+ Cachex.del(:user_cache, "blocked_users_ap_ids:#{user.ap_id}")
+ Cachex.del(:user_cache, "muted_users_ap_ids:#{user.ap_id}")
end
@spec get_cached_by_ap_id(String.t()) :: User.t() | nil
@@ -1342,6 +1356,8 @@ defmodule Pleroma.User do
)
end
+ Cachex.del(:user_cache, "muted_users_ap_ids:#{muter.ap_id}")
+
{:ok, Enum.filter([user_mute, user_notification_mute], & &1)}
end
end
@@ -1350,6 +1366,7 @@ defmodule Pleroma.User do
with {:ok, user_mute} <- UserRelationship.delete_mute(muter, mutee),
{:ok, user_notification_mute} <-
UserRelationship.delete_notification_mute(muter, mutee) do
+ Cachex.del(:user_cache, "muted_users_ap_ids:#{muter.ap_id}")
{:ok, [user_mute, user_notification_mute]}
end
end
@@ -2345,13 +2362,19 @@ defmodule Pleroma.User do
@spec add_to_block(User.t(), User.t()) ::
{:ok, UserRelationship.t()} | {:error, Ecto.Changeset.t()}
defp add_to_block(%User{} = user, %User{} = blocked) do
- UserRelationship.create_block(user, blocked)
+ with {:ok, relationship} <- UserRelationship.create_block(user, blocked) do
+ Cachex.del(:user_cache, "blocked_users_ap_ids:#{user.ap_id}")
+ {:ok, relationship}
+ end
end
@spec add_to_block(User.t(), User.t()) ::
{:ok, UserRelationship.t()} | {:ok, nil} | {:error, Ecto.Changeset.t()}
defp remove_from_block(%User{} = user, %User{} = blocked) do
- UserRelationship.delete_block(user, blocked)
+ with {:ok, relationship} <- UserRelationship.delete_block(user, blocked) do
+ Cachex.del(:user_cache, "blocked_users_ap_ids:#{user.ap_id}")
+ {:ok, relationship}
+ end
end
def set_invisible(user, invisible) do
diff --git a/lib/pleroma/user/search.ex b/lib/pleroma/user/search.ex
index 2dab67211..f1761ef03 100644
--- a/lib/pleroma/user/search.ex
+++ b/lib/pleroma/user/search.ex
@@ -85,7 +85,6 @@ defmodule Pleroma.User.Search do
|> base_query(following)
|> filter_blocked_user(for_user)
|> filter_invisible_users()
- |> filter_discoverable_users()
|> filter_internal_users()
|> filter_blocked_domains(for_user)
|> fts_search(query_string)
@@ -163,10 +162,6 @@ defmodule Pleroma.User.Search do
from(q in query, where: q.invisible == false)
end
- defp filter_discoverable_users(query) do
- from(q in query, where: q.is_discoverable == true)
- end
-
defp filter_internal_users(query) do
from(q in query, where: q.actor_type != "Application")
end
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index 8f3ce1343..1c91bc074 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -123,7 +123,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
# Splice in the child object if we have one.
activity = Maps.put_if_present(activity, :object, object)
- BackgroundWorker.enqueue("fetch_data_for_activity", %{"activity_id" => activity.id})
+ ConcurrentLimiter.limit(Pleroma.Web.RichMedia.Helpers, fn ->
+ Task.start(fn -> Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity) end)
+ end)
{:ok, activity}
else
diff --git a/lib/pleroma/web/activity_pub/mrf/media_proxy_warming_policy.ex b/lib/pleroma/web/activity_pub/mrf/media_proxy_warming_policy.ex
index 0fb05d3c4..816cc89bf 100644
--- a/lib/pleroma/web/activity_pub/mrf/media_proxy_warming_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/media_proxy_warming_policy.ex
@@ -8,7 +8,6 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy do
alias Pleroma.HTTP
alias Pleroma.Web.MediaProxy
- alias Pleroma.Workers.BackgroundWorker
require Logger
@@ -17,7 +16,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy do
recv_timeout: 10_000
]
- def perform(:prefetch, url) do
+ defp prefetch(url) do
# Fetching only proxiable resources
if MediaProxy.enabled?() and MediaProxy.url_proxiable?(url) do
# If preview proxy is enabled, it'll also hit media proxy (so we're caching both requests)
@@ -25,17 +24,25 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy do
Logger.debug("Prefetching #{inspect(url)} as #{inspect(prefetch_url)}")
- HTTP.get(prefetch_url, [], @adapter_options)
+ if Pleroma.Config.get(:env) == :test do
+ fetch(prefetch_url)
+ else
+ ConcurrentLimiter.limit(MediaProxy, fn ->
+ Task.start(fn -> fetch(prefetch_url) end)
+ end)
+ end
end
end
- def perform(:preload, %{"object" => %{"attachment" => attachments}} = _message) do
+ defp fetch(url), do: HTTP.get(url, [], @adapter_options)
+
+ defp preload(%{"object" => %{"attachment" => attachments}} = _message) do
Enum.each(attachments, fn
%{"url" => url} when is_list(url) ->
url
|> Enum.each(fn
%{"href" => href} ->
- BackgroundWorker.enqueue("media_proxy_prefetch", %{"url" => href})
+ prefetch(href)
x ->
Logger.debug("Unhandled attachment URL object #{inspect(x)}")
@@ -51,7 +58,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy do
%{"type" => "Create", "object" => %{"attachment" => attachments} = _object} = message
)
when is_list(attachments) and length(attachments) > 0 do
- BackgroundWorker.enqueue("media_proxy_preload", %{"message" => message})
+ preload(message)
{:ok, message}
end
diff --git a/lib/pleroma/web/activity_pub/side_effects.ex b/lib/pleroma/web/activity_pub/side_effects.ex
index bbff35c36..4d8fb721e 100644
--- a/lib/pleroma/web/activity_pub/side_effects.ex
+++ b/lib/pleroma/web/activity_pub/side_effects.ex
@@ -24,7 +24,6 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.Push
alias Pleroma.Web.Streamer
- alias Pleroma.Workers.BackgroundWorker
require Logger
@@ -191,7 +190,9 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
Object.increase_replies_count(in_reply_to)
end
- BackgroundWorker.enqueue("fetch_data_for_activity", %{"activity_id" => activity.id})
+ ConcurrentLimiter.limit(Pleroma.Web.RichMedia.Helpers, fn ->
+ Task.start(fn -> Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity) end)
+ end)
meta =
meta
diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex
index 4dc45cde3..93c9f436c 100644
--- a/lib/pleroma/web/activity_pub/views/user_view.ex
+++ b/lib/pleroma/web/activity_pub/views/user_view.ex
@@ -110,6 +110,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
"endpoints" => endpoints,
"attachment" => fields,
"tag" => emoji_tags,
+ # Note: key name is indeed "discoverable" (not an error)
"discoverable" => user.is_discoverable,
"capabilities" => capabilities
}
diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex
index 451aa2477..280100c3d 100644
--- a/lib/pleroma/web/api_spec/operations/account_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/account_operation.ex
@@ -139,6 +139,12 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
:query,
%Schema{type: :array, items: VisibilityScope},
"Exclude visibilities"
+ ),
+ Operation.parameter(
+ :with_muted,
+ :query,
+ BooleanLike,
+ "Include reactions from muted acccounts."
)
] ++ pagination_params(),
responses: %{
@@ -618,7 +624,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
allOf: [BooleanLike],
nullable: true,
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
},
diff --git a/lib/pleroma/web/api_spec/operations/emoji_reaction_operation.ex b/lib/pleroma/web/api_spec/operations/emoji_reaction_operation.ex
index 745d41f88..9d0e39fc7 100644
--- a/lib/pleroma/web/api_spec/operations/emoji_reaction_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/emoji_reaction_operation.ex
@@ -24,6 +24,12 @@ defmodule Pleroma.Web.ApiSpec.EmojiReactionOperation do
Operation.parameter(:id, :path, FlakeID, "Status ID", required: true),
Operation.parameter(:emoji, :path, :string, "Filter by a single unicode emoji",
required: nil
+ ),
+ Operation.parameter(
+ :with_muted,
+ :query,
+ :boolean,
+ "Include reactions from muted acccounts."
)
],
security: [%{"oAuth" => ["read:statuses"]}],
diff --git a/lib/pleroma/web/api_spec/operations/status_operation.ex b/lib/pleroma/web/api_spec/operations/status_operation.ex
index b3b6ceb68..4ab918d83 100644
--- a/lib/pleroma/web/api_spec/operations/status_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/status_operation.ex
@@ -31,6 +31,12 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
:query,
%Schema{type: :array, items: FlakeID},
"Array of status IDs"
+ ),
+ Operation.parameter(
+ :with_muted,
+ :query,
+ BooleanLike,
+ "Include reactions from muted acccounts."
)
],
operationId: "StatusController.index",
@@ -67,7 +73,15 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
description: "View information about a status",
operationId: "StatusController.show",
security: [%{"oAuth" => ["read:statuses"]}],
- parameters: [id_param()],
+ parameters: [
+ id_param(),
+ Operation.parameter(
+ :with_muted,
+ :query,
+ BooleanLike,
+ "Include reactions from muted acccounts."
+ )
+ ],
responses: %{
200 => status_response(),
404 => Operation.response("Not Found", "application/json", ApiError)
diff --git a/lib/pleroma/web/api_spec/schemas/account.ex b/lib/pleroma/web/api_spec/schemas/account.ex
index ca79f0747..684f6fc92 100644
--- a/lib/pleroma/web/api_spec/schemas/account.ex
+++ b/lib/pleroma/web/api_spec/schemas/account.ex
@@ -127,7 +127,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Account do
discoverable: %Schema{
type: :boolean,
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{
type: :boolean,
diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
index 784fdc975..7011b7eb1 100644
--- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
@@ -208,7 +208,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
if bot, do: {:ok, "Service"}, else: {:ok, "Person"}
end)
|> 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])
+ # Note: param name is indeed :discoverable (not an error)
|> Maps.put_if_present(:is_discoverable, params[:discoverable])
# What happens here:
@@ -292,7 +294,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
|> render("index.json",
activities: activities,
for: reading_user,
- as: :activity
+ as: :activity,
+ with_muted: Map.get(params, :with_muted, false)
)
else
error -> user_visibility_error(conn, error)
diff --git a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
index 4d9be5240..9e3a584f0 100644
--- a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
@@ -109,7 +109,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
`ids` query param is required
"""
- def index(%{assigns: %{user: user}} = conn, %{ids: ids} = _params) do
+ def index(%{assigns: %{user: user}} = conn, %{ids: ids} = params) do
limit = 100
activities =
@@ -121,7 +121,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
render(conn, "index.json",
activities: activities,
for: user,
- as: :activity
+ as: :activity,
+ with_muted: Map.get(params, :with_muted, false)
)
end
@@ -189,13 +190,14 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
end
@doc "GET /api/v1/statuses/:id"
- def show(%{assigns: %{user: user}} = conn, %{id: id}) do
+ def show(%{assigns: %{user: user}} = conn, %{id: id} = params) do
with %Activity{} = activity <- Activity.get_by_id_with_object(id),
true <- Visibility.visible_for_user?(activity, user) do
try_render(conn, "show.json",
activity: activity,
for: user,
- with_direct_conversation_id: true
+ with_direct_conversation_id: true,
+ with_muted: Map.get(params, :with_muted, false)
)
else
_ -> {:error, :not_found}
diff --git a/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex b/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex
index ac96520a3..852bd0695 100644
--- a/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex
@@ -62,7 +62,8 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> render("index.json",
activities: activities,
for: user,
- as: :activity
+ as: :activity,
+ with_muted: Map.get(params, :with_muted, false)
)
end
@@ -119,7 +120,8 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> render("index.json",
activities: activities,
for: user,
- as: :activity
+ as: :activity,
+ with_muted: Map.get(params, :with_muted, false)
)
end
end
@@ -173,7 +175,8 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> render("index.json",
activities: activities,
for: user,
- as: :activity
+ as: :activity,
+ with_muted: Map.get(params, :with_muted, false)
)
end
end
@@ -202,7 +205,8 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
render(conn, "index.json",
activities: activities,
for: user,
- as: :activity
+ as: :activity,
+ with_muted: Map.get(params, :with_muted, false)
)
else
_e -> render_error(conn, :forbidden, "Error.")
diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex
index 7cbbd3750..2301e21cf 100644
--- a/lib/pleroma/web/mastodon_api/views/status_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/status_view.ex
@@ -19,6 +19,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
alias Pleroma.Web.MastodonAPI.PollView
alias Pleroma.Web.MastodonAPI.StatusView
alias Pleroma.Web.MediaProxy
+ alias Pleroma.Web.PleromaAPI.EmojiReactionController
import Pleroma.Web.ActivityPub.Visibility, only: [get_visibility: 1, visible_for_user?: 2]
@@ -294,21 +295,16 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
end
emoji_reactions =
- with %{data: %{"reactions" => emoji_reactions}} <- object do
- Enum.map(emoji_reactions, fn
- [emoji, users] when is_list(users) ->
- build_emoji_map(emoji, users, opts[:for])
-
- {emoji, users} when is_list(users) ->
- build_emoji_map(emoji, users, opts[:for])
-
- _ ->
- nil
- end)
- |> Enum.reject(&is_nil/1)
- else
- _ -> []
- end
+ object.data
+ |> Map.get("reactions", [])
+ |> EmojiReactionController.filter_allowed_users(
+ opts[:for],
+ Map.get(opts, :with_muted, false)
+ )
+ |> Stream.map(fn {emoji, users} ->
+ build_emoji_map(emoji, users, opts[:for])
+ end)
+ |> Enum.to_list()
# Status muted state (would do 1 request per status unless user mutes are preloaded)
muted =
diff --git a/lib/pleroma/web/metadata/providers/restrict_indexing.ex b/lib/pleroma/web/metadata/providers/restrict_indexing.ex
index 900c2434d..a08a04b4a 100644
--- a/lib/pleroma/web/metadata/providers/restrict_indexing.ex
+++ b/lib/pleroma/web/metadata/providers/restrict_indexing.ex
@@ -6,7 +6,7 @@ defmodule Pleroma.Web.Metadata.Providers.RestrictIndexing do
@behaviour Pleroma.Web.Metadata.Providers.Provider
@moduledoc """
- Restricts indexing of remote users.
+ Restricts indexing of remote and/or non-discoverable users.
"""
@impl true
diff --git a/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex b/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex
index 77564b342..bfc0a1f19 100644
--- a/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex
+++ b/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex
@@ -140,8 +140,8 @@ defmodule Pleroma.Web.PleromaAPI.ChatController do
def index(%{assigns: %{user: %{id: user_id} = user}} = conn, params) do
exclude_users =
- User.blocked_users_ap_ids(user) ++
- if params[:with_muted], do: [], else: User.muted_users_ap_ids(user)
+ User.cached_blocked_users_ap_ids(user) ++
+ if params[:with_muted], do: [], else: User.cached_muted_users_ap_ids(user)
chats =
user_id
diff --git a/lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex b/lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex
index ae199a50f..dd9c746dc 100644
--- a/lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex
+++ b/lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex
@@ -7,6 +7,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionController do
alias Pleroma.Activity
alias Pleroma.Object
+ alias Pleroma.User
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.MastodonAPI.StatusView
alias Pleroma.Web.Plugs.OAuthScopesPlug
@@ -29,13 +30,42 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionController do
%Activity{} = activity <- Activity.get_by_id_with_object(activity_id),
%Object{data: %{"reactions" => reactions}} when is_list(reactions) <-
Object.normalize(activity) do
- reactions = filter(reactions, params)
+ reactions =
+ reactions
+ |> filter(params)
+ |> filter_allowed_users(user, Map.get(params, :with_muted, false))
+
render(conn, "index.json", emoji_reactions: reactions, user: user)
else
_e -> json(conn, [])
end
end
+ def filter_allowed_users(reactions, user, with_muted) do
+ exclude_ap_ids =
+ if is_nil(user) do
+ []
+ else
+ User.cached_blocked_users_ap_ids(user) ++
+ if not with_muted, do: User.cached_muted_users_ap_ids(user), else: []
+ end
+
+ filter_emoji = fn emoji, users ->
+ case Enum.reject(users, &(&1 in exclude_ap_ids)) do
+ [] -> nil
+ users -> {emoji, users}
+ end
+ end
+
+ reactions
+ |> Stream.map(fn
+ [emoji, users] when is_list(users) -> filter_emoji.(emoji, users)
+ {emoji, users} when is_list(users) -> filter_emoji.(emoji, users)
+ _ -> nil
+ end)
+ |> Stream.reject(&is_nil/1)
+ end
+
defp filter(reactions, %{emoji: emoji}) when is_binary(emoji) do
Enum.filter(reactions, fn [e, _] -> e == emoji end)
end
diff --git a/lib/pleroma/web/pleroma_api/views/emoji_reaction_view.ex b/lib/pleroma/web/pleroma_api/views/emoji_reaction_view.ex
index e0f98b50a..110e8a041 100644
--- a/lib/pleroma/web/pleroma_api/views/emoji_reaction_view.ex
+++ b/lib/pleroma/web/pleroma_api/views/emoji_reaction_view.ex
@@ -11,7 +11,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionView do
render_many(emoji_reactions, __MODULE__, "show.json", opts)
end
- def render("show.json", %{emoji_reaction: [emoji, user_ap_ids], user: user}) do
+ def render("show.json", %{emoji_reaction: {emoji, user_ap_ids}, user: user}) do
users = fetch_users(user_ap_ids)
%{
diff --git a/lib/pleroma/web/rich_media/helpers.ex b/lib/pleroma/web/rich_media/helpers.ex
index d67b594b5..442bf9995 100644
--- a/lib/pleroma/web/rich_media/helpers.ex
+++ b/lib/pleroma/web/rich_media/helpers.ex
@@ -78,11 +78,6 @@ defmodule Pleroma.Web.RichMedia.Helpers do
def fetch_data_for_activity(_), do: %{}
- def perform(:fetch, %Activity{} = activity) do
- fetch_data_for_activity(activity)
- :ok
- end
-
def rich_media_get(url) do
headers = [{"user-agent", Pleroma.Application.user_agent() <> "; Bot"}]
diff --git a/lib/pleroma/web/twitter_api/controllers/password_controller.ex b/lib/pleroma/web/twitter_api/controllers/password_controller.ex
index 800ab8954..b1a9d810e 100644
--- a/lib/pleroma/web/twitter_api/controllers/password_controller.ex
+++ b/lib/pleroma/web/twitter_api/controllers/password_controller.ex
@@ -17,6 +17,7 @@ defmodule Pleroma.Web.TwitterAPI.PasswordController do
def reset(conn, %{"token" => token}) do
with %{used: false} = token <- Repo.get_by(PasswordResetToken, %{token: token}),
+ false <- PasswordResetToken.expired?(token),
%User{} = user <- User.get_cached_by_id(token.user_id) do
render(conn, "reset.html", %{
token: token,
diff --git a/lib/pleroma/workers/background_worker.ex b/lib/pleroma/workers/background_worker.ex
index 55b5a13d9..0647c65ae 100644
--- a/lib/pleroma/workers/background_worker.ex
+++ b/lib/pleroma/workers/background_worker.ex
@@ -3,9 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Workers.BackgroundWorker do
- alias Pleroma.Activity
alias Pleroma.User
- alias Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy
use Pleroma.Workers.WorkerHelper, queue: "background"
@@ -32,19 +30,6 @@ defmodule Pleroma.Workers.BackgroundWorker do
{:ok, User.Import.perform(String.to_atom(op), user, identifiers)}
end
- def perform(%Job{args: %{"op" => "media_proxy_preload", "message" => message}}) do
- MediaProxyWarmingPolicy.perform(:preload, message)
- end
-
- def perform(%Job{args: %{"op" => "media_proxy_prefetch", "url" => url}}) do
- MediaProxyWarmingPolicy.perform(:prefetch, url)
- end
-
- def perform(%Job{args: %{"op" => "fetch_data_for_activity", "activity_id" => activity_id}}) do
- activity = Activity.get_by_id(activity_id)
- Pleroma.Web.RichMedia.Helpers.perform(:fetch, activity)
- end
-
def perform(%Job{
args: %{"op" => "move_following", "origin_id" => origin_id, "target_id" => target_id}
}) do
diff --git a/priv/repo/migrations/20200915095704_remove_background_jobs.exs b/priv/repo/migrations/20200915095704_remove_background_jobs.exs
new file mode 100644
index 000000000..9785bfb8a
--- /dev/null
+++ b/priv/repo/migrations/20200915095704_remove_background_jobs.exs
@@ -0,0 +1,22 @@
+defmodule Pleroma.Repo.Migrations.RemoveBackgroundJobs do
+ use Ecto.Migration
+
+ import Ecto.Query, only: [from: 2]
+
+ def up do
+ from(j in "oban_jobs",
+ where:
+ j.queue == ^"background" and
+ fragment("?->>'op'", j.args) in ^[
+ "fetch_data_for_activity",
+ "media_proxy_prefetch",
+ "media_proxy_preload"
+ ] and
+ j.worker == ^"Pleroma.Workers.BackgroundWorker",
+ select: [:id]
+ )
+ |> Pleroma.Repo.delete_all()
+ end
+
+ def down, do: :ok
+end
diff --git a/test/pleroma/config/deprecation_warnings_test.exs b/test/pleroma/config/deprecation_warnings_test.exs
index 0cfed4555..f52629f8a 100644
--- a/test/pleroma/config/deprecation_warnings_test.exs
+++ b/test/pleroma/config/deprecation_warnings_test.exs
@@ -12,7 +12,7 @@ defmodule Pleroma.Config.DeprecationWarningsTest do
alias Pleroma.Config.DeprecationWarnings
test "check_old_mrf_config/0" do
- clear_config([:instance, :rewrite_policy], Pleroma.Web.ActivityPub.MRF.NoOpPolicy)
+ clear_config([:instance, :rewrite_policy], [])
clear_config([:instance, :mrf_transparency], true)
clear_config([:instance, :mrf_transparency_exclusions], [])
diff --git a/test/pleroma/user_search_test.exs b/test/pleroma/user_search_test.exs
index 31d787ffa..de1df2e9c 100644
--- a/test/pleroma/user_search_test.exs
+++ b/test/pleroma/user_search_test.exs
@@ -65,12 +65,13 @@ defmodule Pleroma.UserSearchTest do
assert found_user.id == user.id
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 3001"})
users = User.search("john")
- assert Enum.count(users) == 1
+ assert Enum.count(users) == 2
end
test "excludes service actors from results" do
diff --git a/test/pleroma/web/activity_pub/mrf/media_proxy_warming_policy_test.exs b/test/pleroma/web/activity_pub/mrf/media_proxy_warming_policy_test.exs
index 1710c4d2a..84362ce78 100644
--- a/test/pleroma/web/activity_pub/mrf/media_proxy_warming_policy_test.exs
+++ b/test/pleroma/web/activity_pub/mrf/media_proxy_warming_policy_test.exs
@@ -3,10 +3,10 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicyTest do
- use Pleroma.DataCase
+ use ExUnit.Case
+ use Pleroma.Tests.Helpers
alias Pleroma.HTTP
- alias Pleroma.Tests.ObanHelpers
alias Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy
import Mock
@@ -25,13 +25,13 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicyTest do
setup do: clear_config([:media_proxy, :enabled], true)
test "it prefetches media proxy URIs" do
+ Tesla.Mock.mock(fn %{method: :get, url: "http://example.com/image.jpg"} ->
+ {:ok, %Tesla.Env{status: 200, body: ""}}
+ end)
+
with_mock HTTP, get: fn _, _, _ -> {:ok, []} end do
MediaProxyWarmingPolicy.filter(@message)
- ObanHelpers.perform_all()
- # Performing jobs which has been just enqueued
- ObanHelpers.perform_all()
-
assert called(HTTP.get(:_, :_, :_))
end
end
diff --git a/test/pleroma/web/admin_api/search_test.exs b/test/pleroma/web/admin_api/search_test.exs
index 92a116c65..9bc58640c 100644
--- a/test/pleroma/web/admin_api/search_test.exs
+++ b/test/pleroma/web/admin_api/search_test.exs
@@ -203,6 +203,7 @@ defmodule Pleroma.Web.AdminAPI.SearchTest do
assert count == 1
end
+ # Note: as in Mastodon, `is_discoverable` doesn't anyhow relate to user searchability
test "it returns non-discoverable users" do
insert(:user)
insert(:user, is_discoverable: false)
diff --git a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs
index 58ce76ab8..e8a00dd6b 100644
--- a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs
@@ -436,6 +436,39 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?exclude_visibilities[]=direct")
assert [%{"id" => ^public_activity_id}] = json_response_and_validate_schema(conn, 200)
end
+
+ test "muted reactions", %{user: user, conn: conn} do
+ user2 = insert(:user)
+ User.mute(user, user2)
+ {:ok, activity} = CommonAPI.post(user, %{status: "."})
+ {:ok, _} = CommonAPI.react_with_emoji(activity.id, user2, "🎅")
+
+ result =
+ conn
+ |> get("/api/v1/accounts/#{user.id}/statuses")
+ |> json_response_and_validate_schema(200)
+
+ assert [
+ %{
+ "pleroma" => %{
+ "emoji_reactions" => []
+ }
+ }
+ ] = result
+
+ result =
+ conn
+ |> get("/api/v1/accounts/#{user.id}/statuses?with_muted=true")
+ |> json_response_and_validate_schema(200)
+
+ assert [
+ %{
+ "pleroma" => %{
+ "emoji_reactions" => [%{"count" => 1, "me" => false, "name" => "🎅"}]
+ }
+ }
+ ] = result
+ end
end
defp local_and_remote_activities(%{local: local, remote: remote}) do
diff --git a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
index d95200f99..30d542dfa 100644
--- a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
@@ -328,7 +328,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
end
test "posting a status with OGP link preview", %{conn: conn} do
- Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
+ Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
clear_config([:rich_media, :enabled], true)
conn =
@@ -1197,7 +1197,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
end
test "returns rich-media card", %{conn: conn, user: user} do
- Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
+ Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
{:ok, activity} = CommonAPI.post(user, %{status: "https://example.com/ogp"})
@@ -1242,7 +1242,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
end
test "replaces missing description with an empty string", %{conn: conn, user: user} do
- Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
+ Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
{:ok, activity} = CommonAPI.post(user, %{status: "https://example.com/ogp-missing-data"})
@@ -1759,4 +1759,75 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
assert %Activity{id: ^id, data: %{"to" => [^local]}} = Activity.get_by_id(id)
end
+
+ describe "muted reactions" do
+ test "index" do
+ %{conn: conn, user: user} = oauth_access(["read:statuses"])
+
+ other_user = insert(:user)
+ {:ok, activity} = CommonAPI.post(user, %{status: "test"})
+
+ {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
+ User.mute(user, other_user)
+
+ result =
+ conn
+ |> get("/api/v1/statuses/?ids[]=#{activity.id}")
+ |> json_response_and_validate_schema(200)
+
+ assert [
+ %{
+ "pleroma" => %{
+ "emoji_reactions" => []
+ }
+ }
+ ] = result
+
+ result =
+ conn
+ |> get("/api/v1/statuses/?ids[]=#{activity.id}&with_muted=true")
+ |> json_response_and_validate_schema(200)
+
+ assert [
+ %{
+ "pleroma" => %{
+ "emoji_reactions" => [%{"count" => 1, "me" => false, "name" => "🎅"}]
+ }
+ }
+ ] = result
+ end
+
+ test "show" do
+ # %{conn: conn, user: user, token: token} = oauth_access(["read:statuses"])
+ %{conn: conn, user: user, token: _token} = oauth_access(["read:statuses"])
+
+ other_user = insert(:user)
+ {:ok, activity} = CommonAPI.post(user, %{status: "test"})
+
+ {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
+ User.mute(user, other_user)
+
+ result =
+ conn
+ |> get("/api/v1/statuses/#{activity.id}")
+ |> json_response_and_validate_schema(200)
+
+ assert %{
+ "pleroma" => %{
+ "emoji_reactions" => []
+ }
+ } = result
+
+ result =
+ conn
+ |> get("/api/v1/statuses/#{activity.id}?with_muted=true")
+ |> json_response_and_validate_schema(200)
+
+ assert %{
+ "pleroma" => %{
+ "emoji_reactions" => [%{"count" => 1, "me" => false, "name" => "🎅"}]
+ }
+ } = result
+ end
+ end
end
diff --git a/test/pleroma/web/mastodon_api/controllers/timeline_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/timeline_controller_test.exs
index 4c08ad60a..8356b64d3 100644
--- a/test/pleroma/web/mastodon_api/controllers/timeline_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/timeline_controller_test.exs
@@ -54,6 +54,42 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
assert private_activity.id in status_ids
refute direct_activity.id in status_ids
end
+
+ test "muted emotions", %{user: user, conn: conn} do
+ other_user = insert(:user)
+ {:ok, activity} = CommonAPI.post(user, %{status: "."})
+
+ {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
+ User.mute(user, other_user)
+
+ result =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/timelines/home")
+ |> json_response_and_validate_schema(200)
+
+ assert [
+ %{
+ "pleroma" => %{
+ "emoji_reactions" => []
+ }
+ }
+ ] = result
+
+ result =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/timelines/home?with_muted=true")
+ |> json_response_and_validate_schema(200)
+
+ assert [
+ %{
+ "pleroma" => %{
+ "emoji_reactions" => [%{"count" => 1, "me" => false, "name" => "🎅"}]
+ }
+ }
+ ] = result
+ end
end
describe "public" do
@@ -159,6 +195,48 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
assert length(json_response_and_validate_schema(conn, :ok)) == 1
end
+
+ test "muted emotions", %{conn: conn} do
+ user = insert(:user)
+ token = insert(:oauth_token, user: user, scopes: ["read:statuses"])
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> assign(:token, token)
+
+ other_user = insert(:user)
+ {:ok, activity} = CommonAPI.post(user, %{status: "."})
+
+ {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
+ User.mute(user, other_user)
+
+ result =
+ conn
+ |> get("/api/v1/timelines/public")
+ |> json_response_and_validate_schema(200)
+
+ assert [
+ %{
+ "pleroma" => %{
+ "emoji_reactions" => []
+ }
+ }
+ ] = result
+
+ result =
+ conn
+ |> get("/api/v1/timelines/public?with_muted=true")
+ |> json_response_and_validate_schema(200)
+
+ assert [
+ %{
+ "pleroma" => %{
+ "emoji_reactions" => [%{"count" => 1, "me" => false, "name" => "🎅"}]
+ }
+ }
+ ] = result
+ end
end
defp local_and_remote_activities do
@@ -428,6 +506,44 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
assert id == to_string(activity_one.id)
end
+
+ test "muted emotions", %{user: user, conn: conn} do
+ user2 = insert(:user)
+ user3 = insert(:user)
+ {:ok, activity} = CommonAPI.post(user2, %{status: "."})
+
+ {:ok, _} = CommonAPI.react_with_emoji(activity.id, user3, "🎅")
+ User.mute(user, user3)
+
+ {:ok, list} = Pleroma.List.create("name", user)
+ {:ok, list} = Pleroma.List.follow(list, user2)
+
+ result =
+ conn
+ |> get("/api/v1/timelines/list/#{list.id}")
+ |> json_response_and_validate_schema(200)
+
+ assert [
+ %{
+ "pleroma" => %{
+ "emoji_reactions" => []
+ }
+ }
+ ] = result
+
+ result =
+ conn
+ |> get("/api/v1/timelines/list/#{list.id}?with_muted=true")
+ |> json_response_and_validate_schema(200)
+
+ assert [
+ %{
+ "pleroma" => %{
+ "emoji_reactions" => [%{"count" => 1, "me" => false, "name" => "🎅"}]
+ }
+ }
+ ] = result
+ end
end
describe "hashtag" do
@@ -476,6 +592,48 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
assert [status_none] == json_response_and_validate_schema(all_test, :ok)
end
+
+ test "muted emotions", %{conn: conn} do
+ user = insert(:user)
+ token = insert(:oauth_token, user: user, scopes: ["read:statuses"])
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> assign(:token, token)
+
+ other_user = insert(:user)
+ {:ok, activity} = CommonAPI.post(user, %{status: "test #2hu"})
+
+ {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
+ User.mute(user, other_user)
+
+ result =
+ conn
+ |> get("/api/v1/timelines/tag/2hu")
+ |> json_response_and_validate_schema(200)
+
+ assert [
+ %{
+ "pleroma" => %{
+ "emoji_reactions" => []
+ }
+ }
+ ] = result
+
+ result =
+ conn
+ |> get("/api/v1/timelines/tag/2hu?with_muted=true")
+ |> json_response_and_validate_schema(200)
+
+ assert [
+ %{
+ "pleroma" => %{
+ "emoji_reactions" => [%{"count" => 1, "me" => false, "name" => "🎅"}]
+ }
+ }
+ ] = result
+ end
end
describe "hashtag timeline handling of :restrict_unauthenticated setting" do
diff --git a/test/pleroma/web/mastodon_api/views/status_view_test.exs b/test/pleroma/web/mastodon_api/views/status_view_test.exs
index 665199f97..f2a7469ed 100644
--- a/test/pleroma/web/mastodon_api/views/status_view_test.exs
+++ b/test/pleroma/web/mastodon_api/views/status_view_test.exs
@@ -73,6 +73,50 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
]
end
+ test "doesn't show reactions from muted and blocked users" do
+ user = insert(:user)
+ other_user = insert(:user)
+ third_user = insert(:user)
+
+ {:ok, activity} = CommonAPI.post(user, %{status: "dae cofe??"})
+
+ {:ok, _} = User.mute(user, other_user)
+ {:ok, _} = User.block(other_user, third_user)
+
+ {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
+
+ activity = Repo.get(Activity, activity.id)
+ status = StatusView.render("show.json", activity: activity)
+
+ assert status[:pleroma][:emoji_reactions] == [
+ %{name: "☕", count: 1, me: false}
+ ]
+
+ status = StatusView.render("show.json", activity: activity, for: user)
+
+ assert status[:pleroma][:emoji_reactions] == []
+
+ {:ok, _} = CommonAPI.react_with_emoji(activity.id, third_user, "☕")
+
+ status = StatusView.render("show.json", activity: activity)
+
+ assert status[:pleroma][:emoji_reactions] == [
+ %{name: "☕", count: 2, me: false}
+ ]
+
+ status = StatusView.render("show.json", activity: activity, for: user)
+
+ assert status[:pleroma][:emoji_reactions] == [
+ %{name: "☕", count: 1, me: false}
+ ]
+
+ status = StatusView.render("show.json", activity: activity, for: other_user)
+
+ assert status[:pleroma][:emoji_reactions] == [
+ %{name: "☕", count: 1, me: true}
+ ]
+ end
+
test "loads and returns the direct conversation id when given the `with_direct_conversation_id` option" do
user = insert(:user)
diff --git a/test/pleroma/web/metadata/providers/restrict_indexing_test.exs b/test/pleroma/web/metadata/providers/restrict_indexing_test.exs
index 282d132c8..52399fdc8 100644
--- a/test/pleroma/web/metadata/providers/restrict_indexing_test.exs
+++ b/test/pleroma/web/metadata/providers/restrict_indexing_test.exs
@@ -18,7 +18,7 @@ defmodule Pleroma.Web.Metadata.Providers.RestrictIndexingTest do
}) == []
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(%{
user: %Pleroma.User{local: true, is_discoverable: false}
}) == [{:meta, [name: "robots", content: "noindex, noarchive"], []}]
diff --git a/test/pleroma/web/metadata_test.exs b/test/pleroma/web/metadata_test.exs
deleted file mode 100644
index 8fb946540..000000000
--- a/test/pleroma/web/metadata_test.exs
+++ /dev/null
@@ -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
diff --git a/test/pleroma/web/pleroma_api/controllers/emoji_reaction_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/emoji_reaction_controller_test.exs
index 3deab30d1..bda9c20c6 100644
--- a/test/pleroma/web/pleroma_api/controllers/emoji_reaction_controller_test.exs
+++ b/test/pleroma/web/pleroma_api/controllers/emoji_reaction_controller_test.exs
@@ -106,6 +106,48 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionControllerTest do
result
end
+ test "GET /api/v1/pleroma/statuses/:id/reactions?with_muted=true", %{conn: conn} do
+ user = insert(:user)
+ user2 = insert(:user)
+ user3 = insert(:user)
+
+ token = insert(:oauth_token, user: user, scopes: ["read:statuses"])
+
+ {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
+
+ {:ok, _} = CommonAPI.react_with_emoji(activity.id, user2, "🎅")
+ {:ok, _} = CommonAPI.react_with_emoji(activity.id, user3, "🎅")
+
+ result =
+ conn
+ |> assign(:user, user)
+ |> assign(:token, token)
+ |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
+ |> json_response_and_validate_schema(200)
+
+ assert [%{"name" => "🎅", "count" => 2}] = result
+
+ User.mute(user, user3)
+
+ result =
+ conn
+ |> assign(:user, user)
+ |> assign(:token, token)
+ |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
+ |> json_response_and_validate_schema(200)
+
+ assert [%{"name" => "🎅", "count" => 1}] = result
+
+ result =
+ conn
+ |> assign(:user, user)
+ |> assign(:token, token)
+ |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions?with_muted=true")
+ |> json_response_and_validate_schema(200)
+
+ assert [%{"name" => "🎅", "count" => 2}] = result
+ end
+
test "GET /api/v1/pleroma/statuses/:id/reactions with :show_reactions disabled", %{conn: conn} do
clear_config([:instance, :show_reactions], false)
diff --git a/test/pleroma/web/pleroma_api/views/chat_message_reference_view_test.exs b/test/pleroma/web/pleroma_api/views/chat_message_reference_view_test.exs
index ae8257870..93eef00a2 100644
--- a/test/pleroma/web/pleroma_api/views/chat_message_reference_view_test.exs
+++ b/test/pleroma/web/pleroma_api/views/chat_message_reference_view_test.exs
@@ -48,7 +48,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatMessageReferenceViewTest do
clear_config([:rich_media, :enabled], true)
- Tesla.Mock.mock(fn
+ Tesla.Mock.mock_global(fn
%{url: "https://example.com/ogp"} ->
%Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/ogp.html")}
end)
diff --git a/test/pleroma/web/twitter_api/password_controller_test.exs b/test/pleroma/web/twitter_api/password_controller_test.exs
index a5e9e2178..6d08075cc 100644
--- a/test/pleroma/web/twitter_api/password_controller_test.exs
+++ b/test/pleroma/web/twitter_api/password_controller_test.exs
@@ -31,9 +31,48 @@ defmodule Pleroma.Web.TwitterAPI.PasswordControllerTest do
assert response =~ "<h2>Password Reset for #{user.nickname}</h2>"
end
+
+ test "it returns an error when the token has expired", %{conn: conn} do
+ clear_config([:instance, :password_reset_token_validity], 0)
+
+ user = insert(:user)
+ {:ok, token} = PasswordResetToken.create_token(user)
+
+ :timer.sleep(2000)
+
+ response =
+ conn
+ |> get("/api/pleroma/password_reset/#{token.token}")
+ |> html_response(:ok)
+
+ assert response =~ "<h2>Invalid Token</h2>"
+ end
end
describe "POST /api/pleroma/password_reset" do
+ test "it fails for an expired token", %{conn: conn} do
+ clear_config([:instance, :password_reset_token_validity], 0)
+
+ user = insert(:user)
+ {:ok, token} = PasswordResetToken.create_token(user)
+ :timer.sleep(2000)
+ {:ok, _access_token} = Token.create(insert(:oauth_app), user, %{})
+
+ params = %{
+ "password" => "test",
+ password_confirmation: "test",
+ token: token.token
+ }
+
+ response =
+ conn
+ |> assign(:user, user)
+ |> post("/api/pleroma/password_reset", %{data: params})
+ |> html_response(:ok)
+
+ refute response =~ "<h2>Password changed!</h2>"
+ end
+
test "it returns HTTP 200", %{conn: conn} do
user = insert(:user)
{:ok, token} = PasswordResetToken.create_token(user)