From 8d218ebaf5ab0b72e419068340c40a5ef9744924 Mon Sep 17 00:00:00 2001 From: Alexander Strizhakov Date: Thu, 10 Sep 2020 10:54:57 +0300 Subject: [PATCH 01/13] Moving some background jobs into simple tasks - fetching activity data - attachment prefetching - using limiter to prevent overload --- lib/pleroma/application.ex | 6 +++++ lib/pleroma/web/activity_pub/activity_pub.ex | 4 +++- .../mrf/media_proxy_warming_policy.ex | 19 +++++++++++----- lib/pleroma/web/activity_pub/side_effects.ex | 5 +++-- lib/pleroma/web/rich_media/helpers.ex | 5 ----- lib/pleroma/workers/background_worker.ex | 15 ------------- .../20200915095704_remove_background_jobs.exs | 22 +++++++++++++++++++ .../config/deprecation_warnings_test.exs | 2 +- .../mrf/media_proxy_warming_policy_test.exs | 12 +++++----- .../controllers/status_controller_test.exs | 6 ++--- .../chat_message_reference_view_test.exs | 2 +- 11 files changed, 58 insertions(+), 40 deletions(-) create mode 100644 priv/repo/migrations/20200915095704_remove_background_jobs.exs diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 7c4cd9626..769af1806 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -57,6 +57,7 @@ def start(_type, _args) do setup_instrumenters() load_custom_modules() Pleroma.Docs.JSON.compile() + limiters_setup() adapter = Application.get_env(:tesla, :adapter) @@ -273,4 +274,9 @@ defp http_children(Tesla.Adapter.Gun, _) do end defp http_children(_, _), do: [] + + 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/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index d8f685d38..6008f2f4a 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -123,7 +123,9 @@ def insert(map, local \\ true, fake \\ false, bypass_actor_check \\ false) when # 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 @@ def perform(:prefetch, url) 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 @@ def filter( %{"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 @@ def handle(%{data: %{"type" => "Create"}} = activity, meta) 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/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 @@ def fetch_data_for_activity(%Activity{data: %{"type" => "Create"}} = activity) d 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/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 @@ def perform(%Job{args: %{"op" => op, "user_id" => user_id, "identifiers" => iden {: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/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/mastodon_api/controllers/status_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs index 436608e51..252cae6a9 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 @@ test "fake statuses' preview card is not cached", %{conn: conn} 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 @@ test "on pin removes deletion job, on unpin reschedule deletion" 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 @@ test "returns rich-media card", %{conn: conn, user: user} 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"}) 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 @@ test "it displays a chat message" 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) From e2bf6b1f7ee6115a7eafa78272bdbafe7f4789c5 Mon Sep 17 00:00:00 2001 From: Alexander Strizhakov Date: Mon, 16 Nov 2020 19:22:32 +0300 Subject: [PATCH 02/13] fix for forwarded reports --- lib/pleroma/emails/admin_email.ex | 3 + lib/pleroma/web/activity_pub/activity_pub.ex | 35 +++++---- .../activity_pub_controller_test.exs | 76 +++++++++++++++++++ .../web/activity_pub/activity_pub_test.exs | 25 ++++++ test/support/factory.ex | 32 ++++++-- 5 files changed, 150 insertions(+), 21 deletions(-) diff --git a/lib/pleroma/emails/admin_email.ex b/lib/pleroma/emails/admin_email.ex index 02274554f..d5757c12a 100644 --- a/lib/pleroma/emails/admin_email.ex +++ b/lib/pleroma/emails/admin_email.ex @@ -48,6 +48,9 @@ def report(to, reporter, account, statuses, comment) do status_url = Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, id) "
  • #{status_url}
  • " + %{"id" => id} when is_binary(id) -> + "
  • #{id}
  • " + id when is_binary(id) -> "
  • #{id}
  • " end) diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 35f71b7ae..8f3ce1343 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -332,15 +332,21 @@ defp do_unfollow(follower, followed, activity_id, local) do end @spec flag(map()) :: {:ok, Activity.t()} | {:error, any()} - def flag( - %{ - actor: actor, - context: _context, - account: account, - statuses: statuses, - content: content - } = params - ) do + def flag(params) do + with {:ok, result} <- Repo.transaction(fn -> do_flag(params) end) do + result + end + end + + defp do_flag( + %{ + actor: actor, + context: _context, + account: account, + statuses: statuses, + content: content + } = params + ) do # only accept false as false value local = !(params[:local] == false) forward = !(params[:forward] == false) @@ -358,7 +364,8 @@ def flag( {:ok, activity} <- insert(flag_data, local), {:ok, stripped_activity} <- strip_report_status_data(activity), _ <- notify_and_stream(activity), - :ok <- maybe_federate(stripped_activity) do + :ok <- + maybe_federate(stripped_activity) do User.all_superusers() |> Enum.filter(fn user -> not is_nil(user.email) end) |> Enum.each(fn superuser -> @@ -368,6 +375,8 @@ def flag( end) {:ok, activity} + else + {:error, error} -> Repo.rollback(error) end end @@ -791,10 +800,10 @@ defp restrict_replies(query, %{ where: fragment( """ - ?->>'type' != 'Create' -- This isn't a Create + ?->>'type' != 'Create' -- This isn't a Create OR ?->>'inReplyTo' is null -- this isn't a reply - OR ? && array_remove(?, ?) -- The recipient is us or one of our friends, - -- unless they are the author (because authors + OR ? && array_remove(?, ?) -- The recipient is us or one of our friends, + -- unless they are the author (because authors -- are also part of the recipients). This leads -- to a bug that self-replies by friends won't -- show up. diff --git a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs index 31e48f87f..49eeaeaff 100644 --- a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs @@ -799,6 +799,82 @@ test "it requires authentication", %{conn: conn} do assert json_response(ret_conn, 200) end + + test "forwarded report", %{conn: conn} do + admin = insert(:user, is_admin: true) + actor = insert(:user, local: false) + remote_domain = URI.parse(actor.ap_id).host + reported_user = insert(:user) + + note = insert(:note_activity, user: reported_user) + + data = %{ + "@context" => [ + "https://www.w3.org/ns/activitystreams", + "https://#{remote_domain}/schemas/litepub-0.1.jsonld", + %{ + "@language" => "und" + } + ], + "actor" => actor.ap_id, + "cc" => [ + reported_user.ap_id + ], + "content" => "test", + "context" => "context", + "id" => "http://#{remote_domain}/activities/02be56cf-35e3-46b4-b2c6-47ae08dfee9e", + "nickname" => reported_user.nickname, + "object" => [ + reported_user.ap_id, + %{ + "actor" => %{ + "actor_type" => "Person", + "approval_pending" => false, + "avatar" => "", + "confirmation_pending" => false, + "deactivated" => false, + "display_name" => "test user", + "id" => reported_user.id, + "local" => false, + "nickname" => reported_user.nickname, + "registration_reason" => nil, + "roles" => %{ + "admin" => false, + "moderator" => false + }, + "tags" => [], + "url" => reported_user.ap_id + }, + "content" => "", + "id" => note.data["id"], + "published" => note.data["published"], + "type" => "Note" + } + ], + "published" => note.data["published"], + "state" => "open", + "to" => [], + "type" => "Flag" + } + + conn + |> assign(:valid_signature, true) + |> put_req_header("content-type", "application/activity+json") + |> post("/users/#{reported_user.nickname}/inbox", data) + |> json_response(200) + + ObanHelpers.perform(all_enqueued(worker: ReceiverWorker)) + + assert Pleroma.Repo.aggregate(Activity, :count, :id) == 2 + + ObanHelpers.perform_all() + + Swoosh.TestAssertions.assert_email_sent( + to: {admin.name, admin.email}, + html_body: ~r/Reported Account:/i + ) + + end end describe "GET /users/:nickname/outbox" do diff --git a/test/pleroma/web/activity_pub/activity_pub_test.exs b/test/pleroma/web/activity_pub/activity_pub_test.exs index 3eeb0f735..6cc25dd9e 100644 --- a/test/pleroma/web/activity_pub/activity_pub_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_test.exs @@ -1298,6 +1298,31 @@ test "it can create a Flag activity", assert_called(Utils.maybe_federate(%{activity | data: new_data})) end + + test_with_mock "reverts on error", + %{ + reporter: reporter, + context: context, + target_account: target_account, + reported_activity: reported_activity, + content: content + }, + Utils, + [:passthrough], + maybe_federate: fn _ -> {:error, :reverted} end do + assert {:error, :reverted} = + ActivityPub.flag(%{ + actor: reporter, + context: context, + account: target_account, + statuses: [reported_activity], + content: content + }) + + assert Repo.aggregate(Activity, :count, :id) == 1 + assert Repo.aggregate(Object, :count, :id) == 2 + assert Repo.aggregate(Notification, :count, :id) == 0 + end end test "fetch_activities/2 returns activities addressed to a list " do diff --git a/test/support/factory.ex b/test/support/factory.ex index 80b882ee4..8eb07dc3c 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -24,7 +24,7 @@ def conversation_factory do } end - def user_factory do + def user_factory(attrs \\ %{}) do user = %User{ name: sequence(:name, &"Test テスト User #{&1}"), email: sequence(:email, &"user#{&1}@example.com"), @@ -39,13 +39,29 @@ def user_factory do ap_enabled: true } - %{ - user - | ap_id: User.ap_id(user), - follower_address: User.ap_followers(user), - following_address: User.ap_following(user), - raw_bio: user.bio - } + urls = + if attrs[:local] == false do + base_domain = Enum.random(["domain1.com", "domain2.com", "domain3.com"]) + + ap_id = "https://#{base_domain}/users/#{user.nickname}" + + %{ + ap_id: ap_id, + follower_address: ap_id <> "/followers", + following_address: ap_id <> "/following" + } + else + %{ + ap_id: User.ap_id(user), + follower_address: User.ap_followers(user), + following_address: User.ap_following(user) + } + end + + user + |> Map.put(:raw_bio, user.bio) + |> Map.merge(urls) + |> merge_attributes(attrs) end def user_relationship_factory(attrs \\ %{}) do From a840aefda85c5c32b6904a828f06c84bf4d2a685 Mon Sep 17 00:00:00 2001 From: Alexander Strizhakov Date: Mon, 16 Nov 2020 19:41:03 +0300 Subject: [PATCH 03/13] formatting --- test/pleroma/web/activity_pub/activity_pub_controller_test.exs | 1 - 1 file changed, 1 deletion(-) diff --git a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs index 49eeaeaff..f05f7a487 100644 --- a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs @@ -873,7 +873,6 @@ test "forwarded report", %{conn: conn} do to: {admin.name, admin.email}, html_body: ~r/Reported Account:/i ) - end end From be0b874e1da0178115e27778a55f52d7d28a727a Mon Sep 17 00:00:00 2001 From: Alexander Strizhakov Date: Tue, 17 Nov 2020 19:57:57 +0300 Subject: [PATCH 04/13] fix for mastodon forwarded reports --- lib/pleroma/activity.ex | 10 +++ lib/pleroma/web/activity_pub/utils.ex | 38 ++++++----- test/fixtures/mastodon/application_actor.json | 67 +++++++++++++++++++ .../activity_pub_controller_test.exs | 59 ++++++++++++++++ 4 files changed, 159 insertions(+), 15 deletions(-) create mode 100644 test/fixtures/mastodon/application_actor.json diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index 553834da0..bda5aa616 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -356,4 +356,14 @@ def pinned_by_actor?(%Activity{} = activity) do actor = user_actor(activity) activity.id in actor.pinned_activities end + + @spec get_by_object_ap_id_with_object(String.t()) :: t() | nil + def get_by_object_ap_id_with_object(ap_id) when is_binary(ap_id) do + ap_id + |> Queries.by_object_id() + |> with_preloaded_object() + |> Repo.one() + end + + def get_by_object_ap_id_with_object(_), do: nil end diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 46002bec2..f93909a50 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -710,6 +710,22 @@ defp build_flag_object(%{statuses: statuses}) do Enum.map(statuses || [], &build_flag_object/1) end + defp build_flag_object(%Activity{} = activity) do + activity_actor = User.get_by_ap_id(activity.object.data["actor"]) + + %{ + "type" => "Note", + "id" => activity.data["id"], + "content" => activity.object.data["content"], + "published" => activity.object.data["published"], + "actor" => + AccountView.render( + "show.json", + %{user: activity_actor, skip_visibility_check: true} + ) + } + end + defp build_flag_object(act) when is_map(act) or is_binary(act) do id = case act do @@ -720,22 +736,14 @@ defp build_flag_object(act) when is_map(act) or is_binary(act) do case Activity.get_by_ap_id_with_object(id) do %Activity{} = activity -> - activity_actor = User.get_by_ap_id(activity.object.data["actor"]) + build_flag_object(activity) - %{ - "type" => "Note", - "id" => activity.data["id"], - "content" => activity.object.data["content"], - "published" => activity.object.data["published"], - "actor" => - AccountView.render( - "show.json", - %{user: activity_actor, skip_visibility_check: true} - ) - } - - _ -> - %{"id" => id, "deleted" => true} + nil -> + if activity = Activity.get_by_object_ap_id_with_object(id) do + build_flag_object(activity) + else + %{"id" => id, "deleted" => true} + end end end diff --git a/test/fixtures/mastodon/application_actor.json b/test/fixtures/mastodon/application_actor.json new file mode 100644 index 000000000..2089ea049 --- /dev/null +++ b/test/fixtures/mastodon/application_actor.json @@ -0,0 +1,67 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + { + "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", + "toot": "http://joinmastodon.org/ns#", + "featured": { + "@id": "toot:featured", + "@type": "@id" + }, + "alsoKnownAs": { + "@id": "as:alsoKnownAs", + "@type": "@id" + }, + "movedTo": { + "@id": "as:movedTo", + "@type": "@id" + }, + "schema": "http://schema.org#", + "PropertyValue": "schema:PropertyValue", + "value": "schema:value", + "IdentityProof": "toot:IdentityProof", + "discoverable": "toot:discoverable", + "Device": "toot:Device", + "Ed25519Signature": "toot:Ed25519Signature", + "Ed25519Key": "toot:Ed25519Key", + "Curve25519Key": "toot:Curve25519Key", + "EncryptedMessage": "toot:EncryptedMessage", + "publicKeyBase64": "toot:publicKeyBase64", + "deviceId": "toot:deviceId", + "claim": { + "@type": "@id", + "@id": "toot:claim" + }, + "fingerprintKey": { + "@type": "@id", + "@id": "toot:fingerprintKey" + }, + "identityKey": { + "@type": "@id", + "@id": "toot:identityKey" + }, + "devices": { + "@type": "@id", + "@id": "toot:devices" + }, + "messageFranking": "toot:messageFranking", + "messageType": "toot:messageType", + "cipherText": "toot:cipherText" + } + ], + "id": "https://{{DOMAIN}}/actor", + "type": "Application", + "inbox": "https://{{DOMAIN}}/actor/inbox", + "preferredUsername": "{{DOMAIN}}", + "url": "https://{{DOMAIN}}/about/more?instance_actor=true", + "manuallyApprovesFollowers": true, + "publicKey": { + "id": "https://{{DOMAIN}}/actor#main-key", + "owner": "https://{{DOMAIN}}/actor", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAA0CA08AMIIBCgKCAQEAyi2T2FFZJgRPY+96YQrn\n6J6eF2P60J+nz+/pRc/acv/Nx+NLxxPyXby0F2s60MV7uALRQbBBnf7oNKCd/T4S\nvbr7UXMCWTdaJBpYubMKWT9uBlaUUkUfqL+WTV+IQnlcKtssQ4+AwrAKAZXza8ws\nZypevOsLHzayyEzztmm1KQC9GCUOITCLf7Q6qEhy8z/HuqLBEC0Own0pD7QsbfcS\no1peuZY7g1E/jJ9HR9GqJccMaR0H28KmJ7tT1Yzlyf5uZMRIdPxsoMR9sGLjR2B8\noegSwaf9SogR3ScP395Tt/9Ud1VVzuhpoS8Uy7jKSs+3CuLJsEGoMrib8VyOwadS\n9wIDAQAB\n-----END PUBLIC KEY-----\n" + }, + "endpoints": { + "sharedInbox": "https://{{DOMAIN}}/inbox" + } +} diff --git a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs index f05f7a487..c3d4fcca7 100644 --- a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs @@ -874,6 +874,65 @@ test "forwarded report", %{conn: conn} do html_body: ~r/Reported Account:/i ) end + + test "forwarded report from mastodon", %{conn: conn} do + admin = insert(:user, is_admin: true) + actor = insert(:user, local: false) + remote_domain = URI.parse(actor.ap_id).host + remote_actor = "https://#{remote_domain}/actor" + reported_user = insert(:user) + + note = insert(:note_activity, user: reported_user) + + mock_json_body = + "test/fixtures/mastodon/application_actor.json" + |> File.read!() + |> String.replace("{{DOMAIN}}", remote_domain) + + Tesla.Mock.mock(fn %{url: ^remote_actor} -> + %Tesla.Env{ + status: 200, + body: mock_json_body, + headers: [{"content-type", "application/activity+json"}] + } + end) + + data = %{ + "@context" => "https://www.w3.org/ns/activitystreams", + "actor" => remote_actor, + "content" => "test report", + "id" => "https://#{remote_domain}/e3b12fd1-948c-446e-b93b-a5e67edbe1d8", + "nickname" => reported_user.nickname, + "object" => [ + reported_user.ap_id, + note.data["object"] + ], + "type" => "Flag" + } + + conn + |> assign(:valid_signature, true) + |> put_req_header("content-type", "application/activity+json") + |> post("/users/#{reported_user.nickname}/inbox", data) + |> json_response(200) + + ObanHelpers.perform(all_enqueued(worker: ReceiverWorker)) + + assert Pleroma.Repo.aggregate(Activity, :count, :id) == 2 + + flag_activity = "Flag" |> Pleroma.Activity.Queries.by_type() |> Pleroma.Repo.one() + reported_user_ap_id = reported_user.ap_id + + [^reported_user_ap_id, flag_data] = flag_activity.data["object"] + + Enum.each(~w(actor content id published type), &Map.has_key?(flag_data, &1)) + ObanHelpers.perform_all() + + Swoosh.TestAssertions.assert_email_sent( + to: {admin.name, admin.email}, + html_body: ~r/#{note.data["object"]}/i + ) + end end describe "GET /users/:nickname/outbox" do From 44f3795b8ede118bfce4989ce96df6dd83636ec4 Mon Sep 17 00:00:00 2001 From: Alexander Strizhakov Date: Tue, 17 Nov 2020 20:03:28 +0300 Subject: [PATCH 05/13] changelog entries for fixes --- CHANGELOG.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd90562c2..5e09df22c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,13 +45,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Changed -- Fix ability to update Pleroma Chat push notifications with PUT /api/v1/push/subscription and alert type pleroma:chat_mention - ### Fixed - Config generation: rename `Pleroma.Upload.Filter.ExifTool` to `Pleroma.Upload.Filter.Exiftool`. - S3 Uploads with Elixir 1.11. - 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. + +
    + API +- Statuses were not displayed for Mastodon forwarded reports. + +
    ## [2.2.0] - 2020-11-12 From 8a8c154b4eb5a271c9904a9bb21f4c5f2d985fe4 Mon Sep 17 00:00:00 2001 From: Alexander Strizhakov Date: Wed, 18 Nov 2020 10:03:48 +0300 Subject: [PATCH 06/13] test fixes --- lib/pleroma/web/activity_pub/utils.ex | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index f93909a50..ea1c3a04a 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -702,22 +702,22 @@ def make_flag_data(%{actor: actor, context: context, content: content} = params, def make_flag_data(_, _), do: %{} - defp build_flag_object(%{account: account, statuses: statuses} = _) do - [account.ap_id] ++ build_flag_object(%{statuses: statuses}) + defp build_flag_object(%{account: account, statuses: statuses}) do + [account.ap_id | build_flag_object(%{statuses: statuses})] end defp build_flag_object(%{statuses: statuses}) do Enum.map(statuses || [], &build_flag_object/1) end - defp build_flag_object(%Activity{} = activity) do - activity_actor = User.get_by_ap_id(activity.object.data["actor"]) + defp build_flag_object(%Activity{data: %{"id" => id}, object: %{data: data}}) do + activity_actor = User.get_by_ap_id(data["actor"]) %{ "type" => "Note", - "id" => activity.data["id"], - "content" => activity.object.data["content"], - "published" => activity.object.data["published"], + "id" => id, + "content" => data["content"], + "published" => data["published"], "actor" => AccountView.render( "show.json", From 4aaffe3a10e9aaba4a649ac108221a82e7038387 Mon Sep 17 00:00:00 2001 From: Alexander Strizhakov Date: Wed, 18 Nov 2020 16:36:24 +0300 Subject: [PATCH 07/13] log capture --- test/pleroma/web/activity_pub/activity_pub_controller_test.exs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs index c3d4fcca7..6a1044991 100644 --- a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs @@ -800,6 +800,7 @@ test "it requires authentication", %{conn: conn} do assert json_response(ret_conn, 200) end + @tag capture_log: true test "forwarded report", %{conn: conn} do admin = insert(:user, is_admin: true) actor = insert(:user, local: false) @@ -875,6 +876,7 @@ test "forwarded report", %{conn: conn} do ) end + @tag capture_log: true test "forwarded report from mastodon", %{conn: conn} do admin = insert(:user, is_admin: true) actor = insert(:user, local: false) From 46dab37351994567ddb3a8a6fe654355175fe654 Mon Sep 17 00:00:00 2001 From: Alexander Strizhakov Date: Thu, 19 Nov 2020 15:29:26 +0300 Subject: [PATCH 08/13] little fix --- lib/pleroma/activity.ex | 1 + test/pleroma/activity_test.exs | 16 ++++++++++++++++ .../activity_pub_controller_test.exs | 6 +++--- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index bda5aa616..8559ae6a9 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -362,6 +362,7 @@ def get_by_object_ap_id_with_object(ap_id) when is_binary(ap_id) do ap_id |> Queries.by_object_id() |> with_preloaded_object() + |> first() |> Repo.one() end diff --git a/test/pleroma/activity_test.exs b/test/pleroma/activity_test.exs index ee6a99cc3..3e9fe209e 100644 --- a/test/pleroma/activity_test.exs +++ b/test/pleroma/activity_test.exs @@ -231,4 +231,20 @@ test "all_by_actor_and_id/2" do assert [%Activity{id: ^id1}, %Activity{id: ^id2}] = activities end + + test "get_by_object_ap_id_with_object/1" do + user = insert(:user) + another = insert(:user) + + {:ok, %{id: id, object: %{data: %{"id" => obj_id}}}} = + Pleroma.Web.CommonAPI.post(user, %{status: "cofe"}) + + Pleroma.Web.CommonAPI.favorite(another, id) + + assert obj_id + |> Pleroma.Activity.Queries.by_object_id() + |> Repo.aggregate(:count, :id) == 2 + + assert %{id: ^id} = Activity.get_by_object_ap_id_with_object(obj_id) + end end diff --git a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs index 6a1044991..b577e25dd 100644 --- a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs @@ -882,10 +882,12 @@ test "forwarded report from mastodon", %{conn: conn} do actor = insert(:user, local: false) remote_domain = URI.parse(actor.ap_id).host remote_actor = "https://#{remote_domain}/actor" - reported_user = insert(:user) + [reported_user, another] = insert_list(2, :user) note = insert(:note_activity, user: reported_user) + Pleroma.Web.CommonAPI.favorite(another, note.id) + mock_json_body = "test/fixtures/mastodon/application_actor.json" |> File.read!() @@ -920,8 +922,6 @@ test "forwarded report from mastodon", %{conn: conn} do ObanHelpers.perform(all_enqueued(worker: ReceiverWorker)) - assert Pleroma.Repo.aggregate(Activity, :count, :id) == 2 - flag_activity = "Flag" |> Pleroma.Activity.Queries.by_type() |> Pleroma.Repo.one() reported_user_ap_id = reported_user.ap_id From fcad3e716ad8dc60bd3d94e5b2e0aa18af4c9376 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Thu, 19 Nov 2020 18:08:22 +0300 Subject: [PATCH 09/13] [#2301] Quick fix: users with is_discoverable == false (default!) are included in search results. --- lib/pleroma/user/search.ex | 8 +++++--- test/pleroma/user_search_test.exs | 5 +++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/pleroma/user/search.ex b/lib/pleroma/user/search.ex index 2dab67211..b54111090 100644 --- a/lib/pleroma/user/search.ex +++ b/lib/pleroma/user/search.ex @@ -85,7 +85,7 @@ defp search_query(query_string, for_user, following, top_user_ids) do |> base_query(following) |> filter_blocked_user(for_user) |> filter_invisible_users() - |> filter_discoverable_users() + |> filter_non_discoverable_users() |> filter_internal_users() |> filter_blocked_domains(for_user) |> fts_search(query_string) @@ -163,8 +163,10 @@ defp filter_invisible_users(query) 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) + 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 diff --git a/test/pleroma/user_search_test.exs b/test/pleroma/user_search_test.exs index 31d787ffa..d5ab5a003 100644 --- a/test/pleroma/user_search_test.exs +++ b/test/pleroma/user_search_test.exs @@ -65,12 +65,13 @@ test "excludes invisible users from results" do assert found_user.id == user.id end - test "excludes users when discoverable is false" do + # NOTE: as long as users are non-discoverable by default, we can't filter out most users: #2301 + test "does NOT exclude non-discoverable users from results (as long as it's the default)" 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 From e164c37139c4365d7d46a2a990b364ad26dfdbf7 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Thu, 19 Nov 2020 19:30:02 +0300 Subject: [PATCH 10/13] [#2301] Proper handling of `User.is_discoverable`: users appear in in-service search but are hidden from external services like search bots. --- CHANGELOG.md | 4 +- docs/API/admin_api.md | 2 +- docs/API/differences_in_mastoapi_responses.md | 4 +- lib/pleroma/user/search.ex | 7 --- .../web/activity_pub/views/user_view.ex | 1 + .../api_spec/operations/account_operation.ex | 2 +- lib/pleroma/web/api_spec/schemas/account.ex | 2 +- .../controllers/account_controller.ex | 2 + .../metadata/providers/restrict_indexing.ex | 2 +- test/pleroma/user_search_test.exs | 4 +- test/pleroma/web/admin_api/search_test.exs | 1 + .../providers/restrict_indexing_test.exs | 2 +- test/pleroma/web/metadata_test.exs | 49 ------------------- 13 files changed, 16 insertions(+), 66 deletions(-) delete mode 100644 test/pleroma/web/metadata_test.exs diff --git a/CHANGELOG.md b/CHANGELOG.md index 8658d5440..6caed1123 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,8 @@ 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.). +
    API Changes - 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 `: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`. -
    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/lib/pleroma/user/search.ex b/lib/pleroma/user/search.ex index b54111090..f1761ef03 100644 --- a/lib/pleroma/user/search.ex +++ b/lib/pleroma/user/search.ex @@ -85,7 +85,6 @@ defp search_query(query_string, for_user, following, top_user_ids) do |> base_query(following) |> filter_blocked_user(for_user) |> filter_invisible_users() - |> filter_non_discoverable_users() |> filter_internal_users() |> filter_blocked_domains(for_user) |> fts_search(query_string) @@ -163,12 +162,6 @@ defp filter_invisible_users(query) do from(q in query, where: q.invisible == false) 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 from(q in query, where: q.actor_type != "Application") end 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 @@ def render("user.json", %{user: user}) 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 05595bc2a..280100c3d 100644 --- a/lib/pleroma/web/api_spec/operations/account_operation.ex +++ b/lib/pleroma/web/api_spec/operations/account_operation.ex @@ -624,7 +624,7 @@ defp update_credentials_request 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/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 7ed4603a4..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 @@ def update_credentials(%{assigns: %{user: user}, body_params: params} = conn, _p 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: 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/test/pleroma/user_search_test.exs b/test/pleroma/user_search_test.exs index d5ab5a003..de1df2e9c 100644 --- a/test/pleroma/user_search_test.exs +++ b/test/pleroma/user_search_test.exs @@ -65,8 +65,8 @@ test "excludes invisible users from results" do assert found_user.id == user.id end - # NOTE: as long as users are non-discoverable by default, we can't filter out most users: #2301 - test "does NOT exclude non-discoverable users from results (as long as it's the default)" 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"}) 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 @@ test "it returns unconfirmed user" 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/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 @@ test "for local user" 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 -# 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}) =~ - "" - end - - test "for local user" do - user = insert(:user, is_discoverable: false) - - assert Pleroma.Web.Metadata.build_tags(%{user: user}) =~ - "" - end - - test "for local user set to discoverable" do - user = insert(:user, is_discoverable: true) - - refute Pleroma.Web.Metadata.build_tags(%{user: user}) =~ - "" - 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() == - Pleroma.Web.Metadata.build_tags(%{user: user}) - end - end -end From 0a5b22bc3b1a0011b83e1a77f4f58700266c260a Mon Sep 17 00:00:00 2001 From: Alexander Strizhakov Date: Fri, 20 Nov 2020 11:37:01 +0300 Subject: [PATCH 11/13] start limiters in mix tasks --- lib/mix/pleroma.ex | 1 + lib/pleroma/application.ex | 1 + 2 files changed, 2 insertions(+) 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/application.ex b/lib/pleroma/application.ex index d3c32942c..ced14f87f 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -274,6 +274,7 @@ defp http_children(Tesla.Adapter.Gun, _) do 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)) From e6af7dc77721f487723a6677e37c15c2d996b445 Mon Sep 17 00:00:00 2001 From: Guy Sheffer Date: Sat, 21 Nov 2020 19:57:38 +0200 Subject: [PATCH 12/13] Add missing libmagic for image upload --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 0f4fcd0bb..6a328c88a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -33,7 +33,7 @@ ARG DATA=/var/lib/pleroma RUN echo "http://nl.alpinelinux.org/alpine/latest-stable/community" >> /etc/apk/repositories &&\ apk update &&\ - apk add exiftool imagemagick ncurses postgresql-client &&\ + apk add exiftool imagemagick libmagic ncurses postgresql-client &&\ adduser --system --shell /bin/false --home ${HOME} pleroma &&\ mkdir -p ${DATA}/uploads &&\ mkdir -p ${DATA}/static &&\ From d5f5d0149533b94b1065c19f31a75134e48c492f Mon Sep 17 00:00:00 2001 From: Guy Sheffer Date: Fri, 20 Nov 2020 16:09:10 +0000 Subject: [PATCH 13/13] Translated using Weblate (Hebrew) Currently translated at 100.0% (106 of 106 strings) Translation: Pleroma/Pleroma backend Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma/he/ --- priv/gettext/he/LC_MESSAGES/errors.po | 259 +++++++++++++------------- 1 file changed, 131 insertions(+), 128 deletions(-) diff --git a/priv/gettext/he/LC_MESSAGES/errors.po b/priv/gettext/he/LC_MESSAGES/errors.po index 6d97b620f..7e251383f 100644 --- a/priv/gettext/he/LC_MESSAGES/errors.po +++ b/priv/gettext/he/LC_MESSAGES/errors.po @@ -3,14 +3,17 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-11-10 13:39+0000\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"PO-Revision-Date: 2020-11-21 04:42+0000\n" +"Last-Translator: Guy Sheffer \n" +"Language-Team: Hebrew \n" "Language: he\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 2.5.1\n" +"Plural-Forms: nplurals=4; plural=(n == 1) ? 0 : ((n == 2) ? 1 : ((n > 10 && " +"n % 10 == 0) ? 2 : 3));\n" +"X-Generator: Weblate 4.0.4\n" ## This file is a PO Template file. ## @@ -23,264 +26,264 @@ msgstr "" ## effect: edit them in PO (`.po`) files instead. ## From Ecto.Changeset.cast/4 msgid "can't be blank" -msgstr "" +msgstr "לא יכול להיות ריק" ## From Ecto.Changeset.unique_constraint/3 msgid "has already been taken" -msgstr "" +msgstr "כבר נלקח" ## From Ecto.Changeset.put_change/3 msgid "is invalid" -msgstr "" +msgstr "אינו תקני" ## From Ecto.Changeset.validate_format/3 msgid "has invalid format" -msgstr "" +msgstr "תבנית אינה תקנית" ## From Ecto.Changeset.validate_subset/3 msgid "has an invalid entry" -msgstr "" +msgstr "בעל.ה רשומה לא חוקית" ## From Ecto.Changeset.validate_exclusion/3 msgid "is reserved" -msgstr "" +msgstr "הינו שמור" ## From Ecto.Changeset.validate_confirmation/3 msgid "does not match confirmation" -msgstr "" +msgstr "אינו תורם את האימות" ## From Ecto.Changeset.no_assoc_constraint/3 msgid "is still associated with this entry" -msgstr "" +msgstr "עדיין משויך לרשומה זו" msgid "are still associated with this entry" -msgstr "" +msgstr "עדיין משויכים לרשומה זו" ## From Ecto.Changeset.validate_length/3 msgid "should be %{count} character(s)" msgid_plural "should be %{count} character(s)" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" +msgstr[0] "אחד" +msgstr[1] "שני" +msgstr[2] "בודדים" +msgstr[3] "אחר" msgid "should have %{count} item(s)" msgid_plural "should have %{count} item(s)" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" +msgstr[0] "אחד" +msgstr[1] "שני" +msgstr[2] "בודדים" +msgstr[3] "אחר" msgid "should be at least %{count} character(s)" msgid_plural "should be at least %{count} character(s)" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" +msgstr[0] "אחד" +msgstr[1] "שנים" +msgstr[2] "בודדים" +msgstr[3] "אחר" msgid "should have at least %{count} item(s)" msgid_plural "should have at least %{count} item(s)" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" +msgstr[0] "אחד" +msgstr[1] "שניים" +msgstr[2] "בודדים" +msgstr[3] "אחר" msgid "should be at most %{count} character(s)" msgid_plural "should be at most %{count} character(s)" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" +msgstr[0] "אחד" +msgstr[1] "שניים" +msgstr[2] "בודדים" +msgstr[3] "אחר" msgid "should have at most %{count} item(s)" msgid_plural "should have at most %{count} item(s)" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" +msgstr[0] "אחד" +msgstr[1] "שניים" +msgstr[2] "בודדים" +msgstr[3] "אחר" ## From Ecto.Changeset.validate_number/3 msgid "must be less than %{number}" -msgstr "" +msgstr "חייב להיות מתחת ל-%{number}" msgid "must be greater than %{number}" -msgstr "" +msgstr "חייב להיות מעל ל-%{number}" msgid "must be less than or equal to %{number}" -msgstr "" +msgstr "חייב להיות שווה ל-%{number}" msgid "must be greater than or equal to %{number}" -msgstr "" +msgstr "חייב להיות גדול או שווה ל-%{number}" msgid "must be equal to %{number}" -msgstr "" +msgstr "חייב להיות שווה ל-%{number}" #: lib/pleroma/web/common_api/common_api.ex:505 #, elixir-format msgid "Account not found" -msgstr "" +msgstr "חשבון לא נמצא" #: lib/pleroma/web/common_api/common_api.ex:339 #, elixir-format msgid "Already voted" -msgstr "" +msgstr "הצבעה כבר התבצעה" #: lib/pleroma/web/oauth/oauth_controller.ex:359 #, elixir-format msgid "Bad request" -msgstr "" +msgstr "בקשה שגוייה" #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:426 #, elixir-format msgid "Can't delete object" -msgstr "" +msgstr "לא ניתן למחוק אובייקט" #: lib/pleroma/web/controller_helper.ex:105 #: lib/pleroma/web/controller_helper.ex:111 #, elixir-format msgid "Can't display this activity" -msgstr "" +msgstr "לא ניתן להציג פעילות" #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:285 #, elixir-format msgid "Can't find user" -msgstr "" +msgstr "לא ניתן למצוא משתמש" #: lib/pleroma/web/pleroma_api/controllers/account_controller.ex:61 #, elixir-format msgid "Can't get favorites" -msgstr "" +msgstr "לא ניתן למצוא מועדפים" #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:438 #, elixir-format msgid "Can't like object" -msgstr "" +msgstr "לא ניתן לעשות לחבב אובייקט" #: lib/pleroma/web/common_api/utils.ex:563 #, elixir-format msgid "Cannot post an empty status without attachments" -msgstr "" +msgstr "לא ניתן לשלוח סטטוס ריק ללא קבצים מצורפים" #: lib/pleroma/web/common_api/utils.ex:511 #, elixir-format msgid "Comment must be up to %{max_size} characters" -msgstr "" +msgstr "תגובה חייבת להיות עד %{max_size} תווים" #: lib/pleroma/config/config_db.ex:191 #, elixir-format msgid "Config with params %{params} not found" -msgstr "" +msgstr "הגדרה עם פרמטר %{params} לא נמצאה" #: lib/pleroma/web/common_api/common_api.ex:181 #: lib/pleroma/web/common_api/common_api.ex:185 #, elixir-format msgid "Could not delete" -msgstr "" +msgstr "לא ניתן למחוק" #: lib/pleroma/web/common_api/common_api.ex:231 #, elixir-format msgid "Could not favorite" -msgstr "" +msgstr "לא ניתן לחבב" #: lib/pleroma/web/common_api/common_api.ex:453 #, elixir-format msgid "Could not pin" -msgstr "" +msgstr "לא ניתן לנעוץ" #: lib/pleroma/web/common_api/common_api.ex:278 #, elixir-format msgid "Could not unfavorite" -msgstr "" +msgstr "לא ניתן להסיר חיבוב" #: lib/pleroma/web/common_api/common_api.ex:463 #, elixir-format msgid "Could not unpin" -msgstr "" +msgstr "לא ניתן לבטל נעיצה" #: lib/pleroma/web/common_api/common_api.ex:216 #, elixir-format msgid "Could not unrepeat" -msgstr "" +msgstr "לא ניתן לבטל חזרה" #: lib/pleroma/web/common_api/common_api.ex:512 #: lib/pleroma/web/common_api/common_api.ex:521 #, elixir-format msgid "Could not update state" -msgstr "" +msgstr "לא ניתן לעדכן מצב" #: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:207 #, elixir-format msgid "Error." -msgstr "" +msgstr "שגיאה." #: lib/pleroma/web/twitter_api/twitter_api.ex:106 #, elixir-format msgid "Invalid CAPTCHA" -msgstr "" +msgstr "CAPTCHA לא תקין" #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:116 #: lib/pleroma/web/oauth/oauth_controller.ex:568 #, elixir-format msgid "Invalid credentials" -msgstr "" +msgstr "נתוני אימות לא נכונים" #: lib/pleroma/plugs/ensure_authenticated_plug.ex:38 #, elixir-format msgid "Invalid credentials." -msgstr "" +msgstr "נתוני אימות לא נכונים." #: lib/pleroma/web/common_api/common_api.ex:355 #, elixir-format msgid "Invalid indices" -msgstr "" +msgstr "אינדקס לא תקין" #: lib/pleroma/web/admin_api/controllers/fallback_controller.ex:29 #, elixir-format msgid "Invalid parameters" -msgstr "" +msgstr "פרמטרים לא תקינים" #: lib/pleroma/web/common_api/utils.ex:414 #, elixir-format msgid "Invalid password." -msgstr "" +msgstr "סיסמה לא תקינה." #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:220 #, elixir-format msgid "Invalid request" -msgstr "" +msgstr "בקשה לא תקינה" #: lib/pleroma/web/twitter_api/twitter_api.ex:109 #, elixir-format msgid "Kocaptcha service unavailable" -msgstr "" +msgstr "שירות Kocaptcha לא זמין" #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:112 #, elixir-format msgid "Missing parameters" -msgstr "" +msgstr "פרמטרים חסרים" #: lib/pleroma/web/common_api/utils.ex:547 #, elixir-format msgid "No such conversation" -msgstr "" +msgstr "שיחה לא קיימת" #: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:388 #: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:414 lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:456 #, elixir-format msgid "No such permission_group" -msgstr "" +msgstr "permission_group לא קיים" #: lib/pleroma/plugs/uploaded_media.ex:84 #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:486 lib/pleroma/web/admin_api/controllers/fallback_controller.ex:11 #: lib/pleroma/web/feed/user_controller.ex:71 lib/pleroma/web/ostatus/ostatus_controller.ex:143 #, elixir-format msgid "Not found" -msgstr "" +msgstr "לא נמצא" #: lib/pleroma/web/common_api/common_api.ex:331 #, elixir-format msgid "Poll's author can't vote" -msgstr "" +msgstr "מחבר הסקר לא יכול.ה להצביע" #: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:20 #: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:37 lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:49 @@ -288,215 +291,215 @@ msgstr "" #: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:71 #, elixir-format msgid "Record not found" -msgstr "" +msgstr "רשומה לא נמצאה" #: lib/pleroma/web/admin_api/controllers/fallback_controller.ex:35 #: lib/pleroma/web/feed/user_controller.ex:77 lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:36 #: lib/pleroma/web/ostatus/ostatus_controller.ex:149 #, elixir-format msgid "Something went wrong" -msgstr "" +msgstr "משהו השתבש" #: lib/pleroma/web/common_api/activity_draft.ex:107 #, elixir-format msgid "The message visibility must be direct" -msgstr "" +msgstr "הנראות של ההודעה חייבת להיות ישירה" #: lib/pleroma/web/common_api/utils.ex:573 #, elixir-format msgid "The status is over the character limit" -msgstr "" +msgstr "הסטטוס מעל להגבלת התווים" #: lib/pleroma/plugs/ensure_public_or_authenticated_plug.ex:31 #, elixir-format msgid "This resource requires authentication." -msgstr "" +msgstr "המשאב הזה דורש הרשאה." #: lib/pleroma/plugs/rate_limiter/rate_limiter.ex:206 #, elixir-format msgid "Throttled" -msgstr "" +msgstr "מושנק" #: lib/pleroma/web/common_api/common_api.ex:356 #, elixir-format msgid "Too many choices" -msgstr "" +msgstr "יותר מדיי אפשרויות" #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:443 #, elixir-format msgid "Unhandled activity type" -msgstr "" +msgstr "אין התמודדות לסוג הפעילות" #: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:485 #, elixir-format msgid "You can't revoke your own admin status." -msgstr "" +msgstr "לא ניתן לבטל את הרשאת המנהל של עצמך." #: lib/pleroma/web/oauth/oauth_controller.ex:221 #: lib/pleroma/web/oauth/oauth_controller.ex:308 #, elixir-format msgid "Your account is currently disabled" -msgstr "" +msgstr "החשבון שלך כרגע מבוטל" #: lib/pleroma/web/oauth/oauth_controller.ex:183 #: lib/pleroma/web/oauth/oauth_controller.ex:331 #, elixir-format msgid "Your login is missing a confirmed e-mail address" -msgstr "" +msgstr "חסר לחשבון שלך כתובת דואר אלקטרוני מאושר" #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:390 #, elixir-format msgid "can't read inbox of %{nickname} as %{as_nickname}" -msgstr "" +msgstr "לא ניתן לקרוא את הדואר הנכנס של %{nickname} בתור %{as_nickname}" #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:473 #, elixir-format msgid "can't update outbox of %{nickname} as %{as_nickname}" -msgstr "" +msgstr "לא ניתן לעדכן את חשבון הדואר היוצא של %{nickname} בתור %{as_nickname}" #: lib/pleroma/web/common_api/common_api.ex:471 #, elixir-format msgid "conversation is already muted" -msgstr "" +msgstr "שיחה כבר הושתקה" #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:314 #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:492 #, elixir-format msgid "error" -msgstr "" +msgstr "שגיאה" #: lib/pleroma/web/pleroma_api/controllers/mascot_controller.ex:32 #, elixir-format msgid "mascots can only be images" -msgstr "" +msgstr "קמע יכול להיות רק תמונות" #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:62 #, elixir-format msgid "not found" -msgstr "" +msgstr "לא נמצא" #: lib/pleroma/web/oauth/oauth_controller.ex:394 #, elixir-format msgid "Bad OAuth request." -msgstr "" +msgstr "בקשת OAuth שגוייה." #: lib/pleroma/web/twitter_api/twitter_api.ex:115 #, elixir-format msgid "CAPTCHA already used" -msgstr "" +msgstr "כבר נעשה שימוש ב-CAPTCHA הזה" #: lib/pleroma/web/twitter_api/twitter_api.ex:112 #, elixir-format msgid "CAPTCHA expired" -msgstr "" +msgstr "פג תוקף CAPTCHA" #: lib/pleroma/plugs/uploaded_media.ex:57 #, elixir-format msgid "Failed" -msgstr "" +msgstr "נכשל" #: lib/pleroma/web/oauth/oauth_controller.ex:410 #, elixir-format msgid "Failed to authenticate: %{message}." -msgstr "" +msgstr "נכשל האימות: %{message}." #: lib/pleroma/web/oauth/oauth_controller.ex:441 #, elixir-format msgid "Failed to set up user account." -msgstr "" +msgstr "הגדרת חשבון משתמש נכשלה." #: lib/pleroma/plugs/oauth_scopes_plug.ex:38 #, elixir-format msgid "Insufficient permissions: %{permissions}." -msgstr "" +msgstr "אין מספיק הרשאות: %{permissions}." #: lib/pleroma/plugs/uploaded_media.ex:104 #, elixir-format msgid "Internal Error" -msgstr "" +msgstr "שגיאה פנימית" #: lib/pleroma/web/oauth/fallback_controller.ex:22 #: lib/pleroma/web/oauth/fallback_controller.ex:29 #, elixir-format msgid "Invalid Username/Password" -msgstr "" +msgstr "שם משתמש/סיסמה שגויים" #: lib/pleroma/web/twitter_api/twitter_api.ex:118 #, elixir-format msgid "Invalid answer data" -msgstr "" +msgstr "תשובה שגוייה למידע" #: lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:33 #, elixir-format msgid "Nodeinfo schema version not handled" -msgstr "" +msgstr "Nodeinfo של של גרסת הסכמה לא ניתן לטיפול" #: lib/pleroma/web/oauth/oauth_controller.ex:172 #, elixir-format msgid "This action is outside the authorized scopes" -msgstr "" +msgstr "הפעולה הזו מחוץ לתחומי ההרשאות" #: lib/pleroma/web/oauth/fallback_controller.ex:14 #, elixir-format msgid "Unknown error, please check the details and try again." -msgstr "" +msgstr "שגיאה לא ידועה, יש לבדוק את פרטים ולנסות שוב." #: lib/pleroma/web/oauth/oauth_controller.ex:119 #: lib/pleroma/web/oauth/oauth_controller.ex:158 #, elixir-format msgid "Unlisted redirect_uri." -msgstr "" +msgstr "ניתב redirect_uri לא רשום." #: lib/pleroma/web/oauth/oauth_controller.ex:390 #, elixir-format msgid "Unsupported OAuth provider: %{provider}." -msgstr "" +msgstr "ספק OAuth לא נתמך: %{provider}." #: lib/pleroma/uploaders/uploader.ex:72 #, elixir-format msgid "Uploader callback timeout" -msgstr "" +msgstr "קריאה חזרה של מעלה עברה את הזמן הקצוב" #: lib/pleroma/web/uploader_controller.ex:23 #, elixir-format msgid "bad request" -msgstr "" +msgstr "בקשה שגוייה" #: lib/pleroma/web/twitter_api/twitter_api.ex:103 #, elixir-format msgid "CAPTCHA Error" -msgstr "" +msgstr "שגיאת CAPTCHA" #: lib/pleroma/web/common_api/common_api.ex:290 #, elixir-format msgid "Could not add reaction emoji" -msgstr "" +msgstr "לא ניתן להוסיף סמלון תגובה" #: lib/pleroma/web/common_api/common_api.ex:301 #, elixir-format msgid "Could not remove reaction emoji" -msgstr "" +msgstr "לא ניתן להסיר סמלון תגובה" #: lib/pleroma/web/twitter_api/twitter_api.ex:129 #, elixir-format msgid "Invalid CAPTCHA (Missing parameter: %{name})" -msgstr "" +msgstr "CAPTCHA לא תקני (חסר פרמטר: %{name})" #: lib/pleroma/web/mastodon_api/controllers/list_controller.ex:92 #, elixir-format msgid "List not found" -msgstr "" +msgstr "רשימה לא נמצאה" #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:123 #, elixir-format msgid "Missing parameter: %{name}" -msgstr "" +msgstr "חסר פרמטר: %{name}" #: lib/pleroma/web/oauth/oauth_controller.ex:210 #: lib/pleroma/web/oauth/oauth_controller.ex:321 #, elixir-format msgid "Password reset is required" -msgstr "" +msgstr "נדרש איפוס סיסמה" #: lib/pleroma/tests/auth_test_controller.ex:9 #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:6 lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:6 @@ -533,64 +536,64 @@ msgstr "" #: lib/pleroma/web/uploader_controller.ex:6 lib/pleroma/web/web_finger/web_finger_controller.ex:6 #, elixir-format msgid "Security violation: OAuth scopes check was neither handled nor explicitly skipped." -msgstr "" +msgstr "הפרת אבטחה: OAuth בבדיקת המתחם לא נבדקה או דולגה במכוון." #: lib/pleroma/plugs/ensure_authenticated_plug.ex:28 #, elixir-format msgid "Two-factor authentication enabled, you must use a access token." -msgstr "" +msgstr "אימות דו-שלבי הופעל, יש להזין אסימון כניסה." #: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:210 #, elixir-format msgid "Unexpected error occurred while adding file to pack." -msgstr "" +msgstr "אירעה שגיאה לא צפויה בזמן הוספת הקובץ לחבילה." #: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:138 #, elixir-format msgid "Unexpected error occurred while creating pack." -msgstr "" +msgstr "אירעה שגיאה לא צפויה בזמן יצירת חבילה." #: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:278 #, elixir-format msgid "Unexpected error occurred while removing file from pack." -msgstr "" +msgstr "אירעה שגיאה לא צפויה בזמן הסרת הקובץ מהחבילה." #: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:250 #, elixir-format msgid "Unexpected error occurred while updating file in pack." -msgstr "" +msgstr "אירעה שגיאה לא צפויה בזמן עדכון הקובץ מהחבילה." #: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:179 #, elixir-format msgid "Unexpected error occurred while updating pack metadata." -msgstr "" +msgstr "אירעה שגיאה לא צפויה בזמן עדכון מטא-דאטה של החבילה." #: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:61 #, elixir-format msgid "Web push subscription is disabled on this Pleroma instance" -msgstr "" +msgstr "הרשמה לעדכון ווב בדחיפה מבוטלת בשרת פלרומה זה" #: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:451 #, elixir-format msgid "You can't revoke your own admin/moderator status." -msgstr "" +msgstr "לא ניתן לשלול את סטטוס האדמין/מנהל של עצמך." #: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:126 #, elixir-format msgid "authorization required for timeline view" -msgstr "" +msgstr "הרשאה דרושה על מנת לצפות בציר הזמן" #: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:24 #, elixir-format msgid "Access denied" -msgstr "" +msgstr "גישה נדחית" #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:282 #, elixir-format msgid "This API requires an authenticated user" -msgstr "" +msgstr "ה-API דורש הרשאת משתמש" #: lib/pleroma/plugs/user_is_admin_plug.ex:21 #, elixir-format msgid "User is not an admin." -msgstr "" +msgstr "משתמש אינו מנהל."