From 90a97dfc378f601a57682b1742c2a33a091de867 Mon Sep 17 00:00:00 2001 From: Ilja Date: Thu, 24 Sep 2020 00:34:59 +0200 Subject: [PATCH 01/16] Deprectate strings for SimplePolicy When strings are detected in the simplepolicy, a warning will be given and the config will be changed to use tuples instead --- lib/pleroma/config/deprecation_warnings.ex | 65 +++++++++++++++++- test/config/deprecation_warnings_test.exs | 77 ++++++++++++++++++++++ 2 files changed, 141 insertions(+), 1 deletion(-) diff --git a/lib/pleroma/config/deprecation_warnings.ex b/lib/pleroma/config/deprecation_warnings.ex index 98c4dc9c8..df41b0441 100644 --- a/lib/pleroma/config/deprecation_warnings.ex +++ b/lib/pleroma/config/deprecation_warnings.ex @@ -20,6 +20,68 @@ defmodule Pleroma.Config.DeprecationWarnings do "\n* `config :pleroma, :instance, mrf_transparency_exclusions` is now `config :pleroma, :mrf, transparency_exclusions`"} ] + def check_simple_policy_tuples do + has_strings = + Config.get([:mrf_simple]) + |> Enum.map(fn {_, v} -> v == [] || Enum.max(v) end) + |> Enum.max() + |> is_binary + + if has_strings do + Logger.warn(""" + !!!DEPRECATION WARNING!!! + Your config is using strings in the SimplePolicy configuration instead of tuples. They should work for now, but you are advised to change to the new configuration to prevent possible issues later: + + ``` + config :pleroma, :mrf_simple, + media_removal: ["instance.tld"], + media_nsfw: ["instance.tld"], + federated_timeline_removal: ["instance.tld"], + report_removal: ["instance.tld"], + reject: ["instance.tld"], + followers_only: ["instance.tld"], + accept: ["instance.tld"], + avatar_removal: ["instance.tld"], + banner_removal: ["instance.tld"], + reject_deletes: ["instance.tld"] + ``` + + Is now + + + ``` + config :pleroma, :mrf_simple, + media_removal: [{"instance.tld", "Reason for media removal"}], + media_nsfw: [{"instance.tld", "Reason for media nsfw"}], + federated_timeline_removal: [{"instance.tld", "Reason for federated timeline removal"}], + report_removal: [{"instance.tld", "Reason for report removal"}], + reject: [{"instance.tld", "Reason for reject"}], + followers_only: [{"instance.tld", "Reason for followers only"}], + accept: [{"instance.tld", "Reason for accept"}], + avatar_removal: [{"instance.tld", "Reason for avatar removal"}], + banner_removal: [{"instance.tld", "Reason for banner removal"}], + reject_deletes: [{"instance.tld", "Reason for reject deletes"}] + ``` + """) + + new_config = + Config.get([:mrf_simple]) + |> Enum.map(fn {k, v} -> + {k, + Enum.map(v, fn + {instance, reason} -> {instance, reason} + instance -> {instance, ""} + end)} + end) + + Config.put([:mrf_simple], new_config) + + :ok + else + :ok + end + end + def check_hellthread_threshold do if Config.get([:mrf_hellthread, :threshold]) do Logger.warn(""" @@ -59,7 +121,8 @@ def mrf_user_allowlist do end def warn do - with :ok <- check_hellthread_threshold(), + with :ok <- check_simple_policy_tuples(), + :ok <- check_hellthread_threshold(), :ok <- mrf_user_allowlist(), :ok <- check_old_mrf_config(), :ok <- check_media_proxy_whitelist_config(), diff --git a/test/config/deprecation_warnings_test.exs b/test/config/deprecation_warnings_test.exs index e22052404..ff230db05 100644 --- a/test/config/deprecation_warnings_test.exs +++ b/test/config/deprecation_warnings_test.exs @@ -7,6 +7,83 @@ defmodule Pleroma.Config.DeprecationWarningsTest do alias Pleroma.Config alias Pleroma.Config.DeprecationWarnings + describe "simple policy tuples" do + test "gives warning when there are still strings" do + clear_config([:mrf_simple], + media_removal: ["some.removal"], + media_nsfw: ["some.nsfw"], + federated_timeline_removal: ["some.tl.removal"], + report_removal: ["some.report.removal"], + reject: ["some.reject"], + followers_only: ["some.followers.only"], + accept: ["some.accept"], + avatar_removal: ["some.avatar.removal"], + banner_removal: ["some.banner.removal"], + reject_deletes: ["some.reject.deletes"] + ) + + # TODO: Can I take the actual config and new config instead? Note that it'll need to be clear where you put the reason. + assert capture_log(fn -> DeprecationWarnings.check_simple_policy_tuples() end) =~ + """ + !!!DEPRECATION WARNING!!! + Your config is using strings in the SimplePolicy configuration instead of tuples. They should work for now, but you are advised to change to the new configuration to prevent possible issues later: + + ``` + config :pleroma, :mrf_simple, + media_removal: ["instance.tld"], + media_nsfw: ["instance.tld"], + federated_timeline_removal: ["instance.tld"], + report_removal: ["instance.tld"], + reject: ["instance.tld"], + followers_only: ["instance.tld"], + accept: ["instance.tld"], + avatar_removal: ["instance.tld"], + banner_removal: ["instance.tld"], + reject_deletes: ["instance.tld"] + ``` + + Is now + + + ``` + config :pleroma, :mrf_simple, + media_removal: [{"instance.tld", "Reason for media removal"}], + media_nsfw: [{"instance.tld", "Reason for media nsfw"}], + federated_timeline_removal: [{"instance.tld", "Reason for federated timeline removal"}], + report_removal: [{"instance.tld", "Reason for report removal"}], + reject: [{"instance.tld", "Reason for reject"}], + followers_only: [{"instance.tld", "Reason for followers only"}], + accept: [{"instance.tld", "Reason for accept"}], + avatar_removal: [{"instance.tld", "Reason for avatar removal"}], + banner_removal: [{"instance.tld", "Reason for banner removal"}], + reject_deletes: [{"instance.tld", "Reason for reject deletes"}] + ``` + """ + end + + test "transforms config to tuples" do + clear_config([:mrf_simple], + media_removal: ["some.removal", {"some.other.instance", "Some reason"}] + ) + + expected_config = [ + {:media_removal, [{"some.removal", ""}, {"some.other.instance", "Some reason"}]} + ] + + capture_log(fn -> DeprecationWarnings.check_simple_policy_tuples() end) + + assert Config.get([:mrf_simple]) == expected_config + end + + test "doesn't give a warning with correct config" do + clear_config([:mrf_simple], + media_removal: [{"some.removal", ""}, {"some.other.instance", "Some reason"}] + ) + + assert capture_log(fn -> DeprecationWarnings.check_simple_policy_tuples() end) == "" + end + end + test "check_old_mrf_config/0" do clear_config([:instance, :rewrite_policy], Pleroma.Web.ActivityPub.MRF.NoOpPolicy) clear_config([:instance, :mrf_transparency], true) From 5a909e1bf06a5940089140fd96e07d2f49c4dec5 Mon Sep 17 00:00:00 2001 From: Ilja Date: Thu, 24 Sep 2020 13:10:56 +0200 Subject: [PATCH 02/16] Write better code --- lib/pleroma/config/deprecation_warnings.ex | 7 +++++-- test/config/deprecation_warnings_test.exs | 1 - 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/pleroma/config/deprecation_warnings.ex b/lib/pleroma/config/deprecation_warnings.ex index df41b0441..5ce545959 100644 --- a/lib/pleroma/config/deprecation_warnings.ex +++ b/lib/pleroma/config/deprecation_warnings.ex @@ -23,7 +23,10 @@ defmodule Pleroma.Config.DeprecationWarnings do def check_simple_policy_tuples do has_strings = Config.get([:mrf_simple]) - |> Enum.map(fn {_, v} -> v == [] || Enum.max(v) end) + |> Enum.map(fn + {_, []} -> {} + {_, v} -> Enum.max(v) + end) |> Enum.max() |> is_binary @@ -76,7 +79,7 @@ def check_simple_policy_tuples do Config.put([:mrf_simple], new_config) - :ok + :error else :ok end diff --git a/test/config/deprecation_warnings_test.exs b/test/config/deprecation_warnings_test.exs index ff230db05..b85f903e5 100644 --- a/test/config/deprecation_warnings_test.exs +++ b/test/config/deprecation_warnings_test.exs @@ -22,7 +22,6 @@ test "gives warning when there are still strings" do reject_deletes: ["some.reject.deletes"] ) - # TODO: Can I take the actual config and new config instead? Note that it'll need to be clear where you put the reason. assert capture_log(fn -> DeprecationWarnings.check_simple_policy_tuples() end) =~ """ !!!DEPRECATION WARNING!!! From 0390e0b77c6da3b1e87893e00b5a4a68856bea0d Mon Sep 17 00:00:00 2001 From: Ilja Date: Thu, 24 Sep 2020 21:01:33 +0200 Subject: [PATCH 03/16] Make mrfSimple work with tuples * Changed SimplePolicy * I also grepped in test/ for ':mrf_simple' to see what other things could be affected --- .../web/activity_pub/mrf/simple_policy.ex | 29 +++++---- test/user_test.exs | 2 +- .../activity_pub/mrf/simple_policy_test.exs | 65 ++++++++++--------- test/web/node_info_test.exs | 10 +-- 4 files changed, 60 insertions(+), 46 deletions(-) diff --git a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex index 161177727..22cb242fc 100644 --- a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex @@ -15,7 +15,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do defp check_accept(%{host: actor_host} = _actor_info, object) do accepts = - Config.get([:mrf_simple, :accept]) + instance_list(:accept) |> MRF.subdomains_regex() cond do @@ -28,7 +28,7 @@ defp check_accept(%{host: actor_host} = _actor_info, object) do defp check_reject(%{host: actor_host} = _actor_info, object) do rejects = - Config.get([:mrf_simple, :reject]) + instance_list(:reject) |> MRF.subdomains_regex() if MRF.subdomain_match?(rejects, actor_host) do @@ -44,7 +44,7 @@ defp check_media_removal( ) when length(child_attachment) > 0 do media_removal = - Config.get([:mrf_simple, :media_removal]) + instance_list(:media_removal) |> MRF.subdomains_regex() object = @@ -69,7 +69,7 @@ defp check_media_nsfw( ) when is_map(child_object) do media_nsfw = - Config.get([:mrf_simple, :media_nsfw]) + instance_list(:media_nsfw) |> MRF.subdomains_regex() object = @@ -89,7 +89,7 @@ defp check_media_nsfw(_actor_info, object), do: {:ok, object} defp check_ftl_removal(%{host: actor_host} = _actor_info, object) do timeline_removal = - Config.get([:mrf_simple, :federated_timeline_removal]) + instance_list(:federated_timeline_removal) |> MRF.subdomains_regex() object = @@ -116,7 +116,7 @@ defp intersection(list1, list2) do defp check_followers_only(%{host: actor_host} = _actor_info, object) do followers_only = - Config.get([:mrf_simple, :followers_only]) + instance_list(:followers_only) |> MRF.subdomains_regex() object = @@ -141,7 +141,7 @@ defp check_followers_only(%{host: actor_host} = _actor_info, object) do defp check_report_removal(%{host: actor_host} = _actor_info, %{"type" => "Flag"} = object) do report_removal = - Config.get([:mrf_simple, :report_removal]) + instance_list(:report_removal) |> MRF.subdomains_regex() if MRF.subdomain_match?(report_removal, actor_host) do @@ -155,7 +155,7 @@ defp check_report_removal(_actor_info, object), do: {:ok, object} defp check_avatar_removal(%{host: actor_host} = _actor_info, %{"icon" => _icon} = object) do avatar_removal = - Config.get([:mrf_simple, :avatar_removal]) + instance_list(:avatar_removal) |> MRF.subdomains_regex() if MRF.subdomain_match?(avatar_removal, actor_host) do @@ -169,7 +169,7 @@ defp check_avatar_removal(_actor_info, object), do: {:ok, object} defp check_banner_removal(%{host: actor_host} = _actor_info, %{"image" => _image} = object) do banner_removal = - Config.get([:mrf_simple, :banner_removal]) + instance_list(:banner_removal) |> MRF.subdomains_regex() if MRF.subdomain_match?(banner_removal, actor_host) do @@ -181,12 +181,19 @@ defp check_banner_removal(%{host: actor_host} = _actor_info, %{"image" => _image defp check_banner_removal(_actor_info, object), do: {:ok, object} + defp instance_list(config_key) do + Config.get([:mrf_simple, config_key]) + |> Enum.map(fn + {instance, _} -> instance + end) + end + @impl true def filter(%{"type" => "Delete", "actor" => actor} = object) do %{host: actor_host} = URI.parse(actor) reject_deletes = - Config.get([:mrf_simple, :reject_deletes]) + instance_list(:reject_deletes) |> MRF.subdomains_regex() if MRF.subdomain_match?(reject_deletes, actor_host) do @@ -239,7 +246,7 @@ def describe do mrf_simple = Config.get(:mrf_simple) - |> Enum.map(fn {k, v} -> {k, Enum.reject(v, fn v -> v in exclusions end)} end) + |> Enum.map(fn {k, v} -> {k, Enum.reject(v, fn {v, _} -> v in exclusions end)} end) |> Enum.into(%{}) {:ok, %{mrf_simple: mrf_simple}} diff --git a/test/user_test.exs b/test/user_test.exs index d506f7047..0bfa87972 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -462,7 +462,7 @@ test "it sends a welcome chat message if it is set" do ) test "it sends a welcome chat message when Simple policy applied to local instance" do - Pleroma.Config.put([:mrf_simple, :media_nsfw], ["localhost"]) + Pleroma.Config.put([:mrf_simple, :media_nsfw], [{"localhost", ""}]) welcome_user = insert(:user) Pleroma.Config.put([:welcome, :chat_message, :enabled], true) diff --git a/test/web/activity_pub/mrf/simple_policy_test.exs b/test/web/activity_pub/mrf/simple_policy_test.exs index d7dde62c4..3e9da13b5 100644 --- a/test/web/activity_pub/mrf/simple_policy_test.exs +++ b/test/web/activity_pub/mrf/simple_policy_test.exs @@ -34,7 +34,7 @@ test "is empty" do end test "has a matching host" do - Config.put([:mrf_simple, :media_removal], ["remote.instance"]) + Config.put([:mrf_simple, :media_removal], [{"remote.instance", "Some reason"}]) media_message = build_media_message() local_message = build_local_message() @@ -47,7 +47,7 @@ test "has a matching host" do end test "match with wildcard domain" do - Config.put([:mrf_simple, :media_removal], ["*.remote.instance"]) + Config.put([:mrf_simple, :media_removal], [{"*.remote.instance", "Whatever reason"}]) media_message = build_media_message() local_message = build_local_message() @@ -71,7 +71,7 @@ test "is empty" do end test "has a matching host" do - Config.put([:mrf_simple, :media_nsfw], ["remote.instance"]) + Config.put([:mrf_simple, :media_nsfw], [{"remote.instance", "Whetever"}]) media_message = build_media_message() local_message = build_local_message() @@ -85,7 +85,7 @@ test "has a matching host" do end test "match with wildcard domain" do - Config.put([:mrf_simple, :media_nsfw], ["*.remote.instance"]) + Config.put([:mrf_simple, :media_nsfw], [{"*.remote.instance", "yeah yeah"}]) media_message = build_media_message() local_message = build_local_message() @@ -122,7 +122,7 @@ test "is empty" do end test "has a matching host" do - Config.put([:mrf_simple, :report_removal], ["remote.instance"]) + Config.put([:mrf_simple, :report_removal], [{"remote.instance", "muh"}]) report_message = build_report_message() local_message = build_local_message() @@ -131,7 +131,7 @@ test "has a matching host" do end test "match with wildcard domain" do - Config.put([:mrf_simple, :report_removal], ["*.remote.instance"]) + Config.put([:mrf_simple, :report_removal], [{"*.remote.instance", "suya"}]) report_message = build_report_message() local_message = build_local_message() @@ -166,7 +166,7 @@ test "has a matching host" do |> URI.parse() |> Map.fetch!(:host) - Config.put([:mrf_simple, :federated_timeline_removal], [ftl_message_actor_host]) + Config.put([:mrf_simple, :federated_timeline_removal], [{ftl_message_actor_host, "uwu"}]) local_message = build_local_message() assert {:ok, ftl_message} = SimplePolicy.filter(ftl_message) @@ -187,7 +187,10 @@ test "match with wildcard domain" do |> URI.parse() |> Map.fetch!(:host) - Config.put([:mrf_simple, :federated_timeline_removal], ["*." <> ftl_message_actor_host]) + Config.put([:mrf_simple, :federated_timeline_removal], [ + {"*." <> ftl_message_actor_host, "owo"} + ]) + local_message = build_local_message() assert {:ok, ftl_message} = SimplePolicy.filter(ftl_message) @@ -210,7 +213,9 @@ test "has a matching host but only as:Public in to" do ftl_message = Map.put(ftl_message, "cc", []) - Config.put([:mrf_simple, :federated_timeline_removal], [ftl_message_actor_host]) + Config.put([:mrf_simple, :federated_timeline_removal], [ + {ftl_message_actor_host, "spiderwaifu goes 88w88"} + ]) assert {:ok, ftl_message} = SimplePolicy.filter(ftl_message) refute "https://www.w3.org/ns/activitystreams#Public" in ftl_message["to"] @@ -239,7 +244,7 @@ test "is empty" do end test "activity has a matching host" do - Config.put([:mrf_simple, :reject], ["remote.instance"]) + Config.put([:mrf_simple, :reject], [{"remote.instance", ""}]) remote_message = build_remote_message() @@ -247,7 +252,7 @@ test "activity has a matching host" do end test "activity matches with wildcard domain" do - Config.put([:mrf_simple, :reject], ["*.remote.instance"]) + Config.put([:mrf_simple, :reject], [{"*.remote.instance", ""}]) remote_message = build_remote_message() @@ -255,7 +260,7 @@ test "activity matches with wildcard domain" do end test "actor has a matching host" do - Config.put([:mrf_simple, :reject], ["remote.instance"]) + Config.put([:mrf_simple, :reject], [{"remote.instance", ""}]) remote_user = build_remote_user() @@ -305,7 +310,7 @@ test "has a matching host" do |> URI.parse() |> Map.fetch!(:host) - Config.put([:mrf_simple, :followers_only], [actor_domain]) + Config.put([:mrf_simple, :followers_only], [{actor_domain, ""}]) assert {:ok, new_activity} = SimplePolicy.filter(activity) assert actor.follower_address in new_activity["cc"] @@ -333,7 +338,7 @@ test "is empty" do end test "is not empty but activity doesn't have a matching host" do - Config.put([:mrf_simple, :accept], ["non.matching.remote"]) + Config.put([:mrf_simple, :accept], [{"non.matching.remote", ""}]) local_message = build_local_message() remote_message = build_remote_message() @@ -343,7 +348,7 @@ test "is not empty but activity doesn't have a matching host" do end test "activity has a matching host" do - Config.put([:mrf_simple, :accept], ["remote.instance"]) + Config.put([:mrf_simple, :accept], [{"remote.instance", ""}]) local_message = build_local_message() remote_message = build_remote_message() @@ -353,7 +358,7 @@ test "activity has a matching host" do end test "activity matches with wildcard domain" do - Config.put([:mrf_simple, :accept], ["*.remote.instance"]) + Config.put([:mrf_simple, :accept], [{"*.remote.instance", ""}]) local_message = build_local_message() remote_message = build_remote_message() @@ -363,7 +368,7 @@ test "activity matches with wildcard domain" do end test "actor has a matching host" do - Config.put([:mrf_simple, :accept], ["remote.instance"]) + Config.put([:mrf_simple, :accept], [{"remote.instance", ""}]) remote_user = build_remote_user() @@ -381,7 +386,7 @@ test "is empty" do end test "is not empty but it doesn't have a matching host" do - Config.put([:mrf_simple, :avatar_removal], ["non.matching.remote"]) + Config.put([:mrf_simple, :avatar_removal], [{"non.matching.remote", ""}]) remote_user = build_remote_user() @@ -389,7 +394,7 @@ test "is not empty but it doesn't have a matching host" do end test "has a matching host" do - Config.put([:mrf_simple, :avatar_removal], ["remote.instance"]) + Config.put([:mrf_simple, :avatar_removal], [{"remote.instance", ""}]) remote_user = build_remote_user() {:ok, filtered} = SimplePolicy.filter(remote_user) @@ -398,7 +403,7 @@ test "has a matching host" do end test "match with wildcard domain" do - Config.put([:mrf_simple, :avatar_removal], ["*.remote.instance"]) + Config.put([:mrf_simple, :avatar_removal], [{"*.remote.instance", ""}]) remote_user = build_remote_user() {:ok, filtered} = SimplePolicy.filter(remote_user) @@ -417,7 +422,7 @@ test "is empty" do end test "is not empty but it doesn't have a matching host" do - Config.put([:mrf_simple, :banner_removal], ["non.matching.remote"]) + Config.put([:mrf_simple, :banner_removal], [{"non.matching.remote", ""}]) remote_user = build_remote_user() @@ -425,7 +430,7 @@ test "is not empty but it doesn't have a matching host" do end test "has a matching host" do - Config.put([:mrf_simple, :banner_removal], ["remote.instance"]) + Config.put([:mrf_simple, :banner_removal], [{"remote.instance", ""}]) remote_user = build_remote_user() {:ok, filtered} = SimplePolicy.filter(remote_user) @@ -434,7 +439,7 @@ test "has a matching host" do end test "match with wildcard domain" do - Config.put([:mrf_simple, :banner_removal], ["*.remote.instance"]) + Config.put([:mrf_simple, :banner_removal], [{"*.remote.instance", ""}]) remote_user = build_remote_user() {:ok, filtered} = SimplePolicy.filter(remote_user) @@ -447,7 +452,7 @@ test "match with wildcard domain" do setup do: Config.put([:mrf_simple, :reject_deletes], []) test "it accepts deletions even from rejected servers" do - Config.put([:mrf_simple, :reject], ["remote.instance"]) + Config.put([:mrf_simple, :reject], [{"remote.instance", ""}]) deletion_message = build_remote_deletion_message() @@ -455,7 +460,7 @@ test "it accepts deletions even from rejected servers" do end test "it accepts deletions even from non-whitelisted servers" do - Config.put([:mrf_simple, :accept], ["non.matching.remote"]) + Config.put([:mrf_simple, :accept], [{"non.matching.remote", ""}]) deletion_message = build_remote_deletion_message() @@ -464,10 +469,10 @@ test "it accepts deletions even from non-whitelisted servers" do end describe "when :reject_deletes is not empty but it doesn't have a matching host" do - setup do: Config.put([:mrf_simple, :reject_deletes], ["non.matching.remote"]) + setup do: Config.put([:mrf_simple, :reject_deletes], [{"non.matching.remote", ""}]) test "it accepts deletions even from rejected servers" do - Config.put([:mrf_simple, :reject], ["remote.instance"]) + Config.put([:mrf_simple, :reject], [{"remote.instance", ""}]) deletion_message = build_remote_deletion_message() @@ -475,7 +480,7 @@ test "it accepts deletions even from rejected servers" do end test "it accepts deletions even from non-whitelisted servers" do - Config.put([:mrf_simple, :accept], ["non.matching.remote"]) + Config.put([:mrf_simple, :accept], [{"non.matching.remote", ""}]) deletion_message = build_remote_deletion_message() @@ -484,7 +489,7 @@ test "it accepts deletions even from non-whitelisted servers" do end describe "when :reject_deletes has a matching host" do - setup do: Config.put([:mrf_simple, :reject_deletes], ["remote.instance"]) + setup do: Config.put([:mrf_simple, :reject_deletes], [{"remote.instance", ""}]) test "it rejects the deletion" do deletion_message = build_remote_deletion_message() @@ -494,7 +499,7 @@ test "it rejects the deletion" do end describe "when :reject_deletes match with wildcard domain" do - setup do: Config.put([:mrf_simple, :reject_deletes], ["*.remote.instance"]) + setup do: Config.put([:mrf_simple, :reject_deletes], [{"*.remote.instance", ""}]) test "it rejects the deletion" do deletion_message = build_remote_deletion_message() diff --git a/test/web/node_info_test.exs b/test/web/node_info_test.exs index 06b33607f..077852445 100644 --- a/test/web/node_info_test.exs +++ b/test/web/node_info_test.exs @@ -156,15 +156,17 @@ test "it shows MRF transparency data if enabled", %{conn: conn} do clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.SimplePolicy]) clear_config([:mrf, :transparency], true) - simple_config = %{"reject" => ["example.com"]} + simple_config = %{"reject" => [{"example.com", ""}]} clear_config(:mrf_simple, simple_config) + expected_config = %{"reject" => [["example.com", ""]]} + response = conn |> get("/nodeinfo/2.1.json") |> json_response(:ok) - assert response["metadata"]["federation"]["mrf_simple"] == simple_config + assert response["metadata"]["federation"]["mrf_simple"] == expected_config end test "it performs exclusions from MRF transparency data if configured", %{conn: conn} do @@ -172,10 +174,10 @@ test "it performs exclusions from MRF transparency data if configured", %{conn: clear_config([:mrf, :transparency], true) clear_config([:mrf, :transparency_exclusions], ["other.site"]) - simple_config = %{"reject" => ["example.com", "other.site"]} + simple_config = %{"reject" => [{"example.com", ""}, {"other.site", ""}]} clear_config(:mrf_simple, simple_config) - expected_config = %{"reject" => ["example.com"]} + expected_config = %{"reject" => [["example.com", ""]]} response = conn From 1af61459416887332e226ce13b8078d39aeee914 Mon Sep 17 00:00:00 2001 From: Ilja Date: Thu, 24 Sep 2020 22:02:19 +0200 Subject: [PATCH 04/16] write better code --- lib/pleroma/config/deprecation_warnings.ex | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/lib/pleroma/config/deprecation_warnings.ex b/lib/pleroma/config/deprecation_warnings.ex index 5ce545959..dc80f61e8 100644 --- a/lib/pleroma/config/deprecation_warnings.ex +++ b/lib/pleroma/config/deprecation_warnings.ex @@ -23,12 +23,7 @@ defmodule Pleroma.Config.DeprecationWarnings do def check_simple_policy_tuples do has_strings = Config.get([:mrf_simple]) - |> Enum.map(fn - {_, []} -> {} - {_, v} -> Enum.max(v) - end) - |> Enum.max() - |> is_binary + |> Enum.any?(fn {_, v} -> Enum.any?(v, fn e -> is_binary(e) end) end) if has_strings do Logger.warn(""" From 6446081a131df8194508b95898f220dbe077a45d Mon Sep 17 00:00:00 2001 From: Ilja Date: Fri, 25 Sep 2020 23:36:19 +0200 Subject: [PATCH 05/16] Add tests for setting `:instance, :quarantined_instances` No test was done for quarantined instances yet. I added a factory for followers_only notes and checked * That no followers only post is send when the target server is quarantined * That a followers only post is send when the target server is not quarantined --- test/support/factory.ex | 32 ++++++++++ test/web/activity_pub/publisher_test.exs | 74 ++++++++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/test/support/factory.ex b/test/support/factory.ex index fb82be0c4..b4566e4bd 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -88,6 +88,11 @@ def note_factory(attrs \\ %{}) do } end + def followers_only_note_factory(attrs \\ %{}) do + %Pleroma.Object{data: data} = note_factory(attrs) + %Pleroma.Object{data: Map.merge(data, %{"to" => [data["actor"] <> "/followers"]})} + end + def audio_factory(attrs \\ %{}) do text = sequence(:text, &"lain radio episode #{&1}") @@ -174,6 +179,33 @@ def direct_note_activity_factory do } end + def followers_only_note_activity_factory(attrs \\ %{}) do + user = attrs[:user] || insert(:user) + note = insert(:followers_only_note, user: user) + + data_attrs = attrs[:data_attrs] || %{} + attrs = Map.drop(attrs, [:user, :note, :data_attrs]) + + data = + %{ + "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(), + "type" => "Create", + "actor" => note.data["actor"], + "to" => note.data["to"], + "object" => note.data, + "published" => DateTime.utc_now() |> DateTime.to_iso8601(), + "context" => note.data["context"] + } + |> Map.merge(data_attrs) + + %Pleroma.Activity{ + data: data, + actor: data["actor"], + recipients: data["to"] + } + |> Map.merge(attrs) + end + def note_activity_factory(attrs \\ %{}) do user = attrs[:user] || insert(:user) note = attrs[:note] || insert(:note, user: user) diff --git a/test/web/activity_pub/publisher_test.exs b/test/web/activity_pub/publisher_test.exs index b9388b966..3a9d9ce26 100644 --- a/test/web/activity_pub/publisher_test.exs +++ b/test/web/activity_pub/publisher_test.exs @@ -267,6 +267,80 @@ test "publish to url with with different ports" do end describe "publish/2" do + test_with_mock "doesn't publish a non-public activity to quarantined instances.", + Pleroma.Web.Federator.Publisher, + [:passthrough], + [] do + Config.put([:instance, :quarantined_instances], ["domain.com"]) + + follower = + insert(:user, %{ + local: false, + inbox: "https://domain.com/users/nick1/inbox", + ap_enabled: true + }) + + actor = insert(:user, follower_address: follower.ap_id) + + {:ok, _follower_one} = Pleroma.User.follow(follower, actor) + actor = refresh_record(actor) + + note_activity = + insert(:followers_only_note_activity, + user: actor, + recipients: [follower.ap_id] + ) + + res = Publisher.publish(actor, note_activity) + + assert res == :ok + + assert not called( + Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{ + inbox: "https://domain.com/users/nick1/inbox", + actor_id: actor.id, + id: note_activity.data["id"] + }) + ) + end + + test_with_mock "Publishes a non-public activity to non-quarantined instances.", + Pleroma.Web.Federator.Publisher, + [:passthrough], + [] do + Config.put([:instance, :quarantined_instances], ["somedomain.com"]) + + follower = + insert(:user, %{ + local: false, + inbox: "https://domain.com/users/nick1/inbox", + ap_enabled: true + }) + + actor = insert(:user, follower_address: follower.ap_id) + + {:ok, _follower_one} = Pleroma.User.follow(follower, actor) + actor = refresh_record(actor) + + note_activity = + insert(:followers_only_note_activity, + user: actor, + recipients: [follower.ap_id] + ) + + res = Publisher.publish(actor, note_activity) + + assert res == :ok + + assert called( + Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{ + inbox: "https://domain.com/users/nick1/inbox", + actor_id: actor.id, + id: note_activity.data["id"] + }) + ) + end + test_with_mock "publishes an activity with BCC to all relevant peers.", Pleroma.Web.Federator.Publisher, [:passthrough], From 79ed38836cd67b5a0b1ee2c9bd1617b8d66e5c70 Mon Sep 17 00:00:00 2001 From: Ilja Date: Fri, 2 Oct 2020 14:51:39 +0200 Subject: [PATCH 06/16] Make quarentine work with list of tuples instead of strings --- lib/pleroma/web/activity_pub/mrf.ex | 5 +++++ lib/pleroma/web/activity_pub/mrf/simple_policy.ex | 4 +--- lib/pleroma/web/activity_pub/publisher.ex | 1 + test/web/activity_pub/mrf/mrf_test.exs | 9 +++++++++ test/web/activity_pub/publisher_test.exs | 4 ++-- 5 files changed, 18 insertions(+), 5 deletions(-) diff --git a/lib/pleroma/web/activity_pub/mrf.ex b/lib/pleroma/web/activity_pub/mrf.ex index 5e5361082..28473a134 100644 --- a/lib/pleroma/web/activity_pub/mrf.ex +++ b/lib/pleroma/web/activity_pub/mrf.ex @@ -51,6 +51,11 @@ def subdomain_match?(domains, host) do Enum.any?(domains, fn domain -> Regex.match?(domain, host) end) end + @spec instance_list_from_tuples([{String.t(), String.t()}]) :: [String.t()] + def instance_list_from_tuples(list) do + Enum.map(list, fn {instance, _} -> instance end) + end + @callback describe() :: {:ok | :error, Map.t()} def describe(policies) do diff --git a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex index 22cb242fc..48463f996 100644 --- a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex @@ -183,9 +183,7 @@ defp check_banner_removal(_actor_info, object), do: {:ok, object} defp instance_list(config_key) do Config.get([:mrf_simple, config_key]) - |> Enum.map(fn - {instance, _} -> instance - end) + |> MRF.instance_list_from_tuples() end @impl true diff --git a/lib/pleroma/web/activity_pub/publisher.ex b/lib/pleroma/web/activity_pub/publisher.ex index 9c3956683..e4e9cfb69 100644 --- a/lib/pleroma/web/activity_pub/publisher.ex +++ b/lib/pleroma/web/activity_pub/publisher.ex @@ -126,6 +126,7 @@ defp should_federate?(inbox, public) do quarantined_instances = Config.get([:instance, :quarantined_instances], []) + |> Pleroma.Web.ActivityPub.MRF.instance_list_from_tuples() |> Pleroma.Web.ActivityPub.MRF.subdomains_regex() !Pleroma.Web.ActivityPub.MRF.subdomain_match?(quarantined_instances, host) diff --git a/test/web/activity_pub/mrf/mrf_test.exs b/test/web/activity_pub/mrf/mrf_test.exs index e82c8afa6..042590926 100644 --- a/test/web/activity_pub/mrf/mrf_test.exs +++ b/test/web/activity_pub/mrf/mrf_test.exs @@ -59,6 +59,15 @@ test "matches are case-insensitive" do end end + describe "instance_list_from_tuples/1" do + test "returns a list of instances from a list of {instance, reason} tuples" do + list = [{"some.tld", "a reason"}, {"other.tld", "another reason"}] + expected = ["some.tld", "other.tld"] + + assert MRF.instance_list_from_tuples(list) == expected + end + end + describe "describe/0" do test "it works as expected with noop policy" do clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.NoOpPolicy]) diff --git a/test/web/activity_pub/publisher_test.exs b/test/web/activity_pub/publisher_test.exs index 3a9d9ce26..ed8bed719 100644 --- a/test/web/activity_pub/publisher_test.exs +++ b/test/web/activity_pub/publisher_test.exs @@ -271,7 +271,7 @@ test "publish to url with with different ports" do Pleroma.Web.Federator.Publisher, [:passthrough], [] do - Config.put([:instance, :quarantined_instances], ["domain.com"]) + Config.put([:instance, :quarantined_instances], [{"domain.com", "some reason"}]) follower = insert(:user, %{ @@ -308,7 +308,7 @@ test "publish to url with with different ports" do Pleroma.Web.Federator.Publisher, [:passthrough], [] do - Config.put([:instance, :quarantined_instances], ["somedomain.com"]) + Config.put([:instance, :quarantined_instances], [{"somedomain.com", "some reason"}]) follower = insert(:user, %{ From e8a04e4f8378d56306d5f64e5b11b1a6d708052a Mon Sep 17 00:00:00 2001 From: Ilja Date: Fri, 2 Oct 2020 16:03:20 +0200 Subject: [PATCH 07/16] Deprecate and rewrite settings for quarentine settings * This is for the settings, not yet a DB migration --- lib/pleroma/config/deprecation_warnings.ex | 45 +++++++++++++++++-- test/config/deprecation_warnings_test.exs | 50 ++++++++++++++++++++++ 2 files changed, 92 insertions(+), 3 deletions(-) diff --git a/lib/pleroma/config/deprecation_warnings.ex b/lib/pleroma/config/deprecation_warnings.ex index 12df7fcf5..954ead142 100644 --- a/lib/pleroma/config/deprecation_warnings.ex +++ b/lib/pleroma/config/deprecation_warnings.ex @@ -80,6 +80,44 @@ def check_simple_policy_tuples do end end + def check_quarantined_instances_tuples do + has_strings = + Config.get([:instance, :quarantined_instances]) |> Enum.any?(fn e -> is_binary(e) end) + + if has_strings do + Logger.warn(""" + !!!DEPRECATION WARNING!!! + Your config is using strings in the quarantined_instances configuration instead of tuples. They should work for now, but you are advised to change to the new configuration to prevent possible issues later: + + ``` + config :pleroma, :instance, + quarantined_instances: ["instance.tld"] + ``` + + Is now + + + ``` + config :pleroma, :instance, + quarantined_instances: [{"instance.tld", "Reason for quarantine"}] + ``` + """) + + new_config = + Config.get([:instance, :quarantined_instances]) + |> Enum.map(fn + {instance, reason} -> {instance, reason} + instance -> {instance, ""} + end) + + Config.put([:instance, :quarantined_instances], new_config) + + :error + else + :ok + end + end + def check_hellthread_threshold do if Config.get([:mrf_hellthread, :threshold]) do Logger.warn(""" @@ -94,13 +132,14 @@ def check_hellthread_threshold do end def warn do - with :ok <- check_simple_policy_tuples(), - :ok <- check_hellthread_threshold(), + with :ok <- check_hellthread_threshold(), :ok <- check_old_mrf_config(), :ok <- check_media_proxy_whitelist_config(), :ok <- check_welcome_message_config(), :ok <- check_gun_pool_options(), - :ok <- check_activity_expiration_config() do + :ok <- check_activity_expiration_config(), + :ok <- check_quarantined_instances_tuples(), + :ok <- check_simple_policy_tuples() do :ok else _ -> diff --git a/test/config/deprecation_warnings_test.exs b/test/config/deprecation_warnings_test.exs index 8233cd9bd..497473ac0 100644 --- a/test/config/deprecation_warnings_test.exs +++ b/test/config/deprecation_warnings_test.exs @@ -83,6 +83,56 @@ test "doesn't give a warning with correct config" do end end + describe "quarantined_instances tuples" do + test "gives warning when there are still strings" do + clear_config([:instance, :quarantined_instances], [ + {"domain.com", "some reason"}, + "somedomain.tld" + ]) + + assert capture_log(fn -> DeprecationWarnings.check_quarantined_instances_tuples() end) =~ + """ + !!!DEPRECATION WARNING!!! + Your config is using strings in the quarantined_instances configuration instead of tuples. They should work for now, but you are advised to change to the new configuration to prevent possible issues later: + + ``` + config :pleroma, :instance, + quarantined_instances: ["instance.tld"] + ``` + + Is now + + + ``` + config :pleroma, :instance, + quarantined_instances: [{"instance.tld", "Reason for quarantine"}] + ``` + """ + end + + test "transforms config to tuples" do + clear_config([:instance, :quarantined_instances], [ + {"domain.com", "some reason"}, + "some.tld" + ]) + + expected_config = [{"domain.com", "some reason"}, {"some.tld", ""}] + + capture_log(fn -> DeprecationWarnings.check_quarantined_instances_tuples() end) + + assert Config.get([:instance, :quarantined_instances]) == expected_config + end + + test "doesn't give a warning with correct config" do + clear_config([:instance, :quarantined_instances], [ + {"domain.com", "some reason"}, + {"some.tld", ""} + ]) + + assert capture_log(fn -> DeprecationWarnings.check_quarantined_instances_tuples() end) == "" + end + end + test "check_old_mrf_config/0" do clear_config([:instance, :rewrite_policy], Pleroma.Web.ActivityPub.MRF.NoOpPolicy) clear_config([:instance, :mrf_transparency], true) From 8e725c5acb59bb9295b0ebcd5313379004c08544 Mon Sep 17 00:00:00 2001 From: Ilja Date: Fri, 2 Oct 2020 19:08:04 +0200 Subject: [PATCH 08/16] config :mrf, :transparency_exclusions works with tumples now --- lib/pleroma/web/activity_pub/mrf/simple_policy.ex | 2 +- test/web/node_info_test.exs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex index 48463f996..77d0f2aa3 100644 --- a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex @@ -240,7 +240,7 @@ def filter(object), do: {:ok, object} @impl true def describe do - exclusions = Config.get([:mrf, :transparency_exclusions]) + exclusions = Config.get([:mrf, :transparency_exclusions]) |> MRF.instance_list_from_tuples() mrf_simple = Config.get(:mrf_simple) diff --git a/test/web/node_info_test.exs b/test/web/node_info_test.exs index 077852445..15dd16a82 100644 --- a/test/web/node_info_test.exs +++ b/test/web/node_info_test.exs @@ -172,7 +172,7 @@ test "it shows MRF transparency data if enabled", %{conn: conn} do test "it performs exclusions from MRF transparency data if configured", %{conn: conn} do clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.SimplePolicy]) clear_config([:mrf, :transparency], true) - clear_config([:mrf, :transparency_exclusions], ["other.site"]) + clear_config([:mrf, :transparency_exclusions], [{"other.site", "We don't want them to know"}]) simple_config = %{"reject" => [{"example.com", ""}, {"other.site", ""}]} clear_config(:mrf_simple, simple_config) From 0d1c1736b42456e85aeee5304686fafc2c0d400c Mon Sep 17 00:00:00 2001 From: Ilja Date: Fri, 2 Oct 2020 20:35:51 +0200 Subject: [PATCH 09/16] Deprecate transparency_exclusions * Give deprecation message * Rewrite configs --- lib/pleroma/config/deprecation_warnings.ex | 39 +++++++++++++++++ test/config/deprecation_warnings_test.exs | 50 ++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/lib/pleroma/config/deprecation_warnings.ex b/lib/pleroma/config/deprecation_warnings.ex index 954ead142..d5b2f51db 100644 --- a/lib/pleroma/config/deprecation_warnings.ex +++ b/lib/pleroma/config/deprecation_warnings.ex @@ -118,6 +118,44 @@ def check_quarantined_instances_tuples do end end + def check_transparency_exclusions_tuples do + has_strings = + Config.get([:mrf, :transparency_exclusions]) |> Enum.any?(fn e -> is_binary(e) end) + + if has_strings do + Logger.warn(""" + !!!DEPRECATION WARNING!!! + Your config is using strings in the transparency_exclusions configuration instead of tuples. They should work for now, but you are advised to change to the new configuration to prevent possible issues later: + + ``` + config :pleroma, :mrf, + transparency_exclusions: ["instance.tld"] + ``` + + Is now + + + ``` + config :pleroma, :mrf, + transparency_exclusions: [{"instance.tld", "Reason to exlude transparency"}] + ``` + """) + + new_config = + Config.get([:mrf, :transparency_exclusions]) + |> Enum.map(fn + {instance, reason} -> {instance, reason} + instance -> {instance, ""} + end) + + Config.put([:mrf, :transparency_exclusions], new_config) + + :error + else + :ok + end + end + def check_hellthread_threshold do if Config.get([:mrf_hellthread, :threshold]) do Logger.warn(""" @@ -139,6 +177,7 @@ def warn do :ok <- check_gun_pool_options(), :ok <- check_activity_expiration_config(), :ok <- check_quarantined_instances_tuples(), + :ok <- check_transparency_exclusions_tuples(), :ok <- check_simple_policy_tuples() do :ok else diff --git a/test/config/deprecation_warnings_test.exs b/test/config/deprecation_warnings_test.exs index 497473ac0..d7c2d8dd9 100644 --- a/test/config/deprecation_warnings_test.exs +++ b/test/config/deprecation_warnings_test.exs @@ -133,6 +133,56 @@ test "doesn't give a warning with correct config" do end end + describe "transparency_exclusions tuples" do + test "gives warning when there are still strings" do + clear_config([:mrf, :transparency_exclusions], [ + {"domain.com", "some reason"}, + "somedomain.tld" + ]) + + assert capture_log(fn -> DeprecationWarnings.check_transparency_exclusions_tuples() end) =~ + """ + !!!DEPRECATION WARNING!!! + Your config is using strings in the transparency_exclusions configuration instead of tuples. They should work for now, but you are advised to change to the new configuration to prevent possible issues later: + + ``` + config :pleroma, :mrf, + transparency_exclusions: ["instance.tld"] + ``` + + Is now + + + ``` + config :pleroma, :mrf, + transparency_exclusions: [{"instance.tld", "Reason to exlude transparency"}] + ``` + """ + end + + test "transforms config to tuples" do + clear_config([:mrf, :transparency_exclusions], [ + {"domain.com", "some reason"}, + "some.tld" + ]) + + expected_config = [{"domain.com", "some reason"}, {"some.tld", ""}] + + capture_log(fn -> DeprecationWarnings.check_transparency_exclusions_tuples() end) + + assert Config.get([:mrf, :transparency_exclusions]) == expected_config + end + + test "doesn't give a warning with correct config" do + clear_config([:mrf, :transparency_exclusions], [ + {"domain.com", "some reason"}, + {"some.tld", ""} + ]) + + assert capture_log(fn -> DeprecationWarnings.check_transparency_exclusions_tuples() end) == "" + end + end + test "check_old_mrf_config/0" do clear_config([:instance, :rewrite_policy], Pleroma.Web.ActivityPub.MRF.NoOpPolicy) clear_config([:instance, :mrf_transparency], true) From bd1142105e3c5d63d4157ef0f42c587e9dadd441 Mon Sep 17 00:00:00 2001 From: Ilja Date: Sat, 3 Oct 2020 11:55:16 +0200 Subject: [PATCH 10/16] make linter happy --- test/config/deprecation_warnings_test.exs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/config/deprecation_warnings_test.exs b/test/config/deprecation_warnings_test.exs index d7c2d8dd9..ecb4fa7f7 100644 --- a/test/config/deprecation_warnings_test.exs +++ b/test/config/deprecation_warnings_test.exs @@ -179,7 +179,8 @@ test "doesn't give a warning with correct config" do {"some.tld", ""} ]) - assert capture_log(fn -> DeprecationWarnings.check_transparency_exclusions_tuples() end) == "" + assert capture_log(fn -> DeprecationWarnings.check_transparency_exclusions_tuples() end) == + "" end end From 3ea3f49268e8f28e3b64340d855341eff9e3cf1a Mon Sep 17 00:00:00 2001 From: Ilja Date: Sat, 3 Oct 2020 12:08:09 +0200 Subject: [PATCH 11/16] change config/description.exs so all changed settings use tuples --- config/description.exs | 77 ++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/config/description.exs b/config/description.exs index ac3dfbb2b..285ef5845 100644 --- a/config/description.exs +++ b/config/description.exs @@ -769,12 +769,12 @@ }, %{ key: :quarantined_instances, - type: {:list, :string}, + type: {:list, :tuple}, description: - "List of ActivityPub instances where private (DMs, followers-only) activities will not be sent", + "List of ActivityPub instances where private (DMs, followers-only) activities will not be sent and the reason for doing so", suggestions: [ - "quarantined.com", - "*.quarantined.com" + {"quarantined.com", "Reason"}, + {"*.quarantined.com", "Reason"} ] }, %{ @@ -1577,11 +1577,11 @@ %{ key: :transparency_exclusions, label: "MRF transparency exclusions", - type: {:list, :string}, + type: {:list, :tuple}, description: "Exclude specific instance names from MRF transparency. The use of the exclusions feature will be disclosed in nodeinfo as a boolean value.", suggestions: [ - "exclusion.com" + {"exclusion.com", "Reason for exclusion"} ] } ] @@ -1597,65 +1597,70 @@ children: [ %{ key: :media_removal, - type: {:list, :string}, - description: "List of instances to strip media attachments from", - suggestions: ["example.com", "*.example.com"] + type: {:list, :tuple}, + description: + "List of instances to strip media attachments from and the reason for doing so", + suggestions: [{"example.com", "Some reason"}, {"*.example.com", "Another reason"}] }, %{ key: :media_nsfw, label: "Media NSFW", - type: {:list, :string}, - description: "List of instances to tag all media as NSFW (sensitive) from", - suggestions: ["example.com", "*.example.com"] + type: {:list, :tuple}, + description: + "List of instances to tag all media as NSFW (sensitive) from and the reason for doing so", + suggestions: [{"example.com", "Some reason"}, {"*.example.com", "Another reason"}] }, %{ key: :federated_timeline_removal, - type: {:list, :string}, + type: {:list, :tuple}, description: - "List of instances to remove from the Federated (aka The Whole Known Network) Timeline", - suggestions: ["example.com", "*.example.com"] + "List of instances to remove from the Federated Timeline (aka The Whole Known Network) and the reason for doing so", + suggestions: [{"example.com", "Some reason"}, {"*.example.com", "Another reason"}] }, %{ key: :reject, - type: {:list, :string}, - description: "List of instances to reject activities from (except deletes)", - suggestions: ["example.com", "*.example.com"] + type: {:list, :tuple}, + description: + "List of instances to reject activities (except deletes) from and the reason for doing so", + suggestions: [{"example.com", "Some reason"}, {"*.example.com", "Another reason"}] }, %{ key: :accept, - type: {:list, :string}, - description: "List of instances to only accept activities from (except deletes)", - suggestions: ["example.com", "*.example.com"] + type: {:list, :tuple}, + description: + "List of instances to only accept activities (except deletes) from and the reason for doing so", + suggestions: [{"example.com", "Some reason"}, {"*.example.com", "Another reason"}] }, %{ key: :followers_only, - type: {:list, :string}, - description: "Force posts from the given instances to be visible by followers only", - suggestions: ["example.com", "*.example.com"] + type: {:list, :tuple}, + description: + "Force posts from the given instances to be visible by followers only and the reason for doing so", + suggestions: [{"example.com", "Some reason"}, {"*.example.com", "Another reason"}] }, %{ key: :report_removal, - type: {:list, :string}, - description: "List of instances to reject reports from", - suggestions: ["example.com", "*.example.com"] + type: {:list, :tuple}, + description: "List of instances to reject reports from and the reason for doing so", + suggestions: [{"example.com", "Some reason"}, {"*.example.com", "Another reason"}] }, %{ key: :avatar_removal, - type: {:list, :string}, - description: "List of instances to strip avatars from", - suggestions: ["example.com", "*.example.com"] + type: {:list, :tuple}, + description: "List of instances to strip avatars from and the reason for doing so", + suggestions: [{"example.com", "Some reason"}, {"*.example.com", "Another reason"}] }, %{ key: :banner_removal, - type: {:list, :string}, - description: "List of instances to strip banners from", - suggestions: ["example.com", "*.example.com"] + type: {:list, :tuple}, + description: "List of instances to strip banners from and the reason for doing so", + suggestions: [{"example.com", "Some reason"}, {"*.example.com", "Another reason"}] }, %{ key: :reject_deletes, - type: {:list, :string}, - description: "List of instances to reject deletions from", - suggestions: ["example.com", "*.example.com"] + type: {:list, :tuple}, + description: "List of instances to reject deletions from and the reason for doing so", + suggestions: [{"example.com", "Some reason"}, {"*.example.com", "Another reason"}] } ] }, From 9a213ee9ee15c87d66c0fd3e06c1915fbc2c2f12 Mon Sep 17 00:00:00 2001 From: Ilja Date: Mon, 5 Oct 2020 11:26:08 +0200 Subject: [PATCH 12/16] Fixed deprecation warning checks When a setting was deprecated, the code would stop checking for the rest of the possible deprications. This also meant that the settings weren't rewritten to the new settings for deprecated settings besides the first one. --- lib/pleroma/config/deprecation_warnings.ex | 29 +++++++++++----------- test/config/deprecation_warnings_test.exs | 6 ++--- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/lib/pleroma/config/deprecation_warnings.ex b/lib/pleroma/config/deprecation_warnings.ex index d5b2f51db..d5f68568a 100644 --- a/lib/pleroma/config/deprecation_warnings.ex +++ b/lib/pleroma/config/deprecation_warnings.ex @@ -170,20 +170,21 @@ def check_hellthread_threshold do end def warn do - with :ok <- check_hellthread_threshold(), - :ok <- check_old_mrf_config(), - :ok <- check_media_proxy_whitelist_config(), - :ok <- check_welcome_message_config(), - :ok <- check_gun_pool_options(), - :ok <- check_activity_expiration_config(), - :ok <- check_quarantined_instances_tuples(), - :ok <- check_transparency_exclusions_tuples(), - :ok <- check_simple_policy_tuples() do - :ok - else - _ -> - :error - end + [ + check_hellthread_threshold(), + check_old_mrf_config(), + check_media_proxy_whitelist_config(), + check_welcome_message_config(), + check_gun_pool_options(), + check_activity_expiration_config(), + check_quarantined_instances_tuples(), + check_transparency_exclusions_tuples(), + check_simple_policy_tuples() + ] + |> Enum.reduce(:ok, fn + :ok, :ok -> :ok + _, _ -> :error + end) end def check_welcome_message_config do diff --git a/test/config/deprecation_warnings_test.exs b/test/config/deprecation_warnings_test.exs index ecb4fa7f7..d93e51cf2 100644 --- a/test/config/deprecation_warnings_test.exs +++ b/test/config/deprecation_warnings_test.exs @@ -69,7 +69,7 @@ test "transforms config to tuples" do {:media_removal, [{"some.removal", ""}, {"some.other.instance", "Some reason"}]} ] - capture_log(fn -> DeprecationWarnings.check_simple_policy_tuples() end) + capture_log(fn -> DeprecationWarnings.warn() end) assert Config.get([:mrf_simple]) == expected_config end @@ -118,7 +118,7 @@ test "transforms config to tuples" do expected_config = [{"domain.com", "some reason"}, {"some.tld", ""}] - capture_log(fn -> DeprecationWarnings.check_quarantined_instances_tuples() end) + capture_log(fn -> DeprecationWarnings.warn() end) assert Config.get([:instance, :quarantined_instances]) == expected_config end @@ -168,7 +168,7 @@ test "transforms config to tuples" do expected_config = [{"domain.com", "some reason"}, {"some.tld", ""}] - capture_log(fn -> DeprecationWarnings.check_transparency_exclusions_tuples() end) + capture_log(fn -> DeprecationWarnings.warn() end) assert Config.get([:mrf, :transparency_exclusions]) == expected_config end From 513103829641faca5501d1d3123ce3c077d7da25 Mon Sep 17 00:00:00 2001 From: Ilja Date: Mon, 5 Oct 2020 14:13:11 +0200 Subject: [PATCH 13/16] Add database migrations * SimplePolicy * quarentine * transparency_exclusions --- ...05123100_simple_policy_string_to_tuple.exs | 40 ++++++++++++ ...00_quarantained_policy_string_to_tuple.exs | 61 +++++++++++++++++++ ...ransparency_exclusions_string_to_tuple.exs | 61 +++++++++++++++++++ 3 files changed, 162 insertions(+) create mode 100644 priv/repo/migrations/20201005123100_simple_policy_string_to_tuple.exs create mode 100644 priv/repo/migrations/20201005124600_quarantained_policy_string_to_tuple.exs create mode 100644 priv/repo/migrations/20201005132900_transparency_exclusions_string_to_tuple.exs diff --git a/priv/repo/migrations/20201005123100_simple_policy_string_to_tuple.exs b/priv/repo/migrations/20201005123100_simple_policy_string_to_tuple.exs new file mode 100644 index 000000000..77a4a7311 --- /dev/null +++ b/priv/repo/migrations/20201005123100_simple_policy_string_to_tuple.exs @@ -0,0 +1,40 @@ +defmodule Pleroma.Repo.Migrations.SimplePolicyStringToTuple do + use Ecto.Migration + + alias Pleroma.ConfigDB + + def up, do: ConfigDB.get_by_params(%{group: :pleroma, key: :mrf_simple}) |> update_to_tuples + def down, do: ConfigDB.get_by_params(%{group: :pleroma, key: :mrf_simple}) |> update_to_strings + + defp update_to_tuples(%{value: value}) do + new_value = + value + |> Enum.map(fn {k, v} -> + {k, + Enum.map(v, fn + {instance, reason} -> {instance, reason} + instance -> {instance, ""} + end)} + end) + + ConfigDB.update_or_create(%{group: :pleroma, key: :mrf_simple, value: new_value}) + end + + defp update_to_tuples(nil), do: {:ok, nil} + + defp update_to_strings(%{value: value}) do + new_value = + value + |> Enum.map(fn {k, v} -> + {k, + Enum.map(v, fn + {instance, _} -> instance + instance -> instance + end)} + end) + + ConfigDB.update_or_create(%{group: :pleroma, key: :mrf_simple, value: new_value}) + end + + defp update_to_strings(nil), do: {:ok, nil} +end diff --git a/priv/repo/migrations/20201005124600_quarantained_policy_string_to_tuple.exs b/priv/repo/migrations/20201005124600_quarantained_policy_string_to_tuple.exs new file mode 100644 index 000000000..b924e4638 --- /dev/null +++ b/priv/repo/migrations/20201005124600_quarantained_policy_string_to_tuple.exs @@ -0,0 +1,61 @@ +defmodule Pleroma.Repo.Migrations.QuarantainedStringToTuple do + use Ecto.Migration + + alias Pleroma.ConfigDB + + def up, + do: + ConfigDB.get_by_params(%{group: :pleroma, key: :instance}) + |> update_quarantined_instances_to_tuples + + def down, + do: + ConfigDB.get_by_params(%{group: :pleroma, key: :instance}) + |> update_quarantined_instances_to_strings + + defp update_quarantined_instances_to_tuples(%{value: settings}) do + settings |> List.keyfind(:quarantined_instances, 0) |> update_to_tuples + end + + defp update_quarantined_instances_to_tuples(nil), do: {:ok, nil} + + defp update_to_tuples({:quarantined_instances, instance_list}) do + new_value = + instance_list + |> Enum.map(fn + {v, r} -> {v, r} + v -> {v, ""} + end) + + ConfigDB.update_or_create(%{ + group: :pleroma, + key: :instance, + value: [quarantined_instances: new_value] + }) + end + + defp update_to_tuples(nil), do: {:ok, nil} + + defp update_quarantined_instances_to_strings(%{value: settings}) do + settings |> List.keyfind(:quarantined_instances, 0) |> update_to_strings + end + + defp update_quarantined_instances_to_strings(nil), do: {:ok, nil} + + defp update_to_strings({:quarantined_instances, instance_list}) do + new_value = + instance_list + |> Enum.map(fn + {v, _} -> v + v -> v + end) + + ConfigDB.update_or_create(%{ + group: :pleroma, + key: :instance, + value: [quarantined_instances: new_value] + }) + end + + defp update_to_strings(nil), do: {:ok, nil} +end diff --git a/priv/repo/migrations/20201005132900_transparency_exclusions_string_to_tuple.exs b/priv/repo/migrations/20201005132900_transparency_exclusions_string_to_tuple.exs new file mode 100644 index 000000000..6516083a7 --- /dev/null +++ b/priv/repo/migrations/20201005132900_transparency_exclusions_string_to_tuple.exs @@ -0,0 +1,61 @@ +defmodule Pleroma.Repo.Migrations.TransparencyExclusionsStringToTuple do + use Ecto.Migration + + alias Pleroma.ConfigDB + + def up, + do: + ConfigDB.get_by_params(%{group: :pleroma, key: :mrf}) + |> update_transparency_exclusions_instances_to_tuples + + def down, + do: + ConfigDB.get_by_params(%{group: :pleroma, key: :mrf}) + |> update_transparency_exclusions_instances_to_strings + + defp update_transparency_exclusions_instances_to_tuples(%{value: settings}) do + settings |> List.keyfind(:transparency_exclusions, 0) |> update_to_tuples + end + + defp update_transparency_exclusions_instances_to_tuples(nil), do: {:ok, nil} + + defp update_to_tuples({:transparency_exclusions, instance_list}) do + new_value = + instance_list + |> Enum.map(fn + {v, r} -> {v, r} + v -> {v, ""} + end) + + ConfigDB.update_or_create(%{ + group: :pleroma, + key: :mrf, + value: [transparency_exclusions: new_value] + }) + end + + defp update_to_tuples(nil), do: {:ok, nil} + + defp update_transparency_exclusions_instances_to_strings(%{value: settings}) do + settings |> List.keyfind(:transparency_exclusions, 0) |> update_to_strings + end + + defp update_transparency_exclusions_instances_to_strings(nil), do: {:ok, nil} + + defp update_to_strings({:transparency_exclusions, instance_list}) do + new_value = + instance_list + |> Enum.map(fn + {v, _} -> v + v -> v + end) + + ConfigDB.update_or_create(%{ + group: :pleroma, + key: :mrf, + value: [transparency_exclusions: new_value] + }) + end + + defp update_to_strings(nil), do: {:ok, nil} +end From 0ab917ec6f627a13e286233ce8fd5df9dbd19102 Mon Sep 17 00:00:00 2001 From: Ilja Date: Fri, 23 Oct 2020 20:27:13 +0200 Subject: [PATCH 14/16] Return maps in node_info It's easiest (and imo most proper) to use tuples {"instance, "reason"} in BE, but for FE maps like %{"instance": "instance", "reason", "reason"} are better. I changed it so that node_info returns maps now for simple_policy and quarantined instances. --- .../web/activity_pub/mrf/simple_policy.ex | 3 +++ .../web/mastodon_api/views/instance_view.ex | 6 +++++- test/pleroma/web/node_info_test.exs | 20 +++++++++++++++++-- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex index 77d0f2aa3..7a2b5c5d5 100644 --- a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex @@ -245,6 +245,9 @@ def describe do mrf_simple = Config.get(:mrf_simple) |> Enum.map(fn {k, v} -> {k, Enum.reject(v, fn {v, _} -> v in exclusions end)} end) + |> Enum.map(fn {k, v} -> + {k, Enum.map(v, fn {i, r} -> %{"instance" => i, "reason" => r} end)} + end) |> Enum.into(%{}) {:ok, %{mrf_simple: mrf_simple}} diff --git a/lib/pleroma/web/mastodon_api/views/instance_view.ex b/lib/pleroma/web/mastodon_api/views/instance_view.ex index ea2d3aa9c..ebddaba60 100644 --- a/lib/pleroma/web/mastodon_api/views/instance_view.ex +++ b/lib/pleroma/web/mastodon_api/views/instance_view.ex @@ -88,7 +88,11 @@ def federation do {:ok, data} = MRF.describe() data - |> Map.merge(%{quarantined_instances: quarantined}) + |> Map.merge(%{ + quarantined_instances: + quarantined + |> Enum.map(fn {instance, reason} -> %{"instance" => instance, "reason" => reason} end) + }) else %{} end diff --git a/test/pleroma/web/node_info_test.exs b/test/pleroma/web/node_info_test.exs index 15dd16a82..1d9ce6d51 100644 --- a/test/pleroma/web/node_info_test.exs +++ b/test/pleroma/web/node_info_test.exs @@ -152,6 +152,22 @@ test "it shows default features flags", %{conn: conn} do ) end + test "it shows quarantined instances data if enabled", %{conn: conn} do + clear_config([:mrf, :transparency], true) + + quarantined_instances = [{"example.com", ""}] + clear_config([:instance, :quarantined_instances], quarantined_instances) + + expected_config = [%{"instance" => "example.com", "reason" => ""}] + + response = + conn + |> get("/nodeinfo/2.1.json") + |> json_response(:ok) + + assert response["metadata"]["federation"]["quarantined_instances"] == expected_config + end + test "it shows MRF transparency data if enabled", %{conn: conn} do clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.SimplePolicy]) clear_config([:mrf, :transparency], true) @@ -159,7 +175,7 @@ test "it shows MRF transparency data if enabled", %{conn: conn} do simple_config = %{"reject" => [{"example.com", ""}]} clear_config(:mrf_simple, simple_config) - expected_config = %{"reject" => [["example.com", ""]]} + expected_config = %{"reject" => [%{"instance" => "example.com", "reason" => ""}]} response = conn @@ -177,7 +193,7 @@ test "it performs exclusions from MRF transparency data if configured", %{conn: simple_config = %{"reject" => [{"example.com", ""}, {"other.site", ""}]} clear_config(:mrf_simple, simple_config) - expected_config = %{"reject" => [["example.com", ""]]} + expected_config = %{"reject" => [%{"instance" => "example.com", "reason" => ""}]} response = conn From f4092e96d1f0a11085cbe5b8613e4913b3ef9eb9 Mon Sep 17 00:00:00 2001 From: Ilja Date: Fri, 20 Nov 2020 13:48:28 +0100 Subject: [PATCH 15/16] Change what nodeinfo returns without breaking backwards compatibility * Only for SimplePolicy for now * I added an extra mrf_simple_info key that has an object as value. The object contains only relevant extra info --- .../web/activity_pub/mrf/simple_policy.ex | 18 +++- test/pleroma/web/node_info_test.exs | 100 +++++++++++++----- 2 files changed, 90 insertions(+), 28 deletions(-) diff --git a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex index 7a2b5c5d5..fe2118f74 100644 --- a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex @@ -242,14 +242,26 @@ def filter(object), do: {:ok, object} def describe do exclusions = Config.get([:mrf, :transparency_exclusions]) |> MRF.instance_list_from_tuples() - mrf_simple = + mrf_simple_excluded = Config.get(:mrf_simple) |> Enum.map(fn {k, v} -> {k, Enum.reject(v, fn {v, _} -> v in exclusions end)} end) + + mrf_simple = + mrf_simple_excluded |> Enum.map(fn {k, v} -> - {k, Enum.map(v, fn {i, r} -> %{"instance" => i, "reason" => r} end)} + {k, Enum.map(v, fn {instance, _} -> instance end)} end) |> Enum.into(%{}) - {:ok, %{mrf_simple: mrf_simple}} + mrf_simple_info = + mrf_simple_excluded + |> Enum.map(fn {k, v} -> {k, Enum.reject(v, fn {_, reason} -> reason == "" end)} end) + |> Enum.reject(fn {_, v} -> v == [] end) + |> Enum.map(fn {k, l} -> + {k, l |> Enum.map(fn {i, r} -> {i, %{"reason" => r}} end) |> Enum.into(%{})} + end) + |> Enum.into(%{}) + + {:ok, %{mrf_simple: mrf_simple, mrf_simple_info: mrf_simple_info}} end end diff --git a/test/pleroma/web/node_info_test.exs b/test/pleroma/web/node_info_test.exs index 1d9ce6d51..952e26d4f 100644 --- a/test/pleroma/web/node_info_test.exs +++ b/test/pleroma/web/node_info_test.exs @@ -168,39 +168,89 @@ test "it shows quarantined instances data if enabled", %{conn: conn} do assert response["metadata"]["federation"]["quarantined_instances"] == expected_config end - test "it shows MRF transparency data if enabled", %{conn: conn} do - clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.SimplePolicy]) - clear_config([:mrf, :transparency], true) + describe "MRF SimplePolicy" do + setup do + clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.SimplePolicy]) + clear_config([:mrf, :transparency], true) + end - simple_config = %{"reject" => [{"example.com", ""}]} - clear_config(:mrf_simple, simple_config) + test "shows MRF transparency data if enabled", %{conn: conn} do + simple_config = %{"reject" => [{"example.com", ""}]} + clear_config(:mrf_simple, simple_config) - expected_config = %{"reject" => [%{"instance" => "example.com", "reason" => ""}]} + expected_config = %{"reject" => ["example.com"]} - response = - conn - |> get("/nodeinfo/2.1.json") - |> json_response(:ok) + response = + conn + |> get("/nodeinfo/2.1.json") + |> json_response(:ok) - assert response["metadata"]["federation"]["mrf_simple"] == expected_config - end + assert response["metadata"]["federation"]["mrf_simple"] == expected_config + end - test "it performs exclusions from MRF transparency data if configured", %{conn: conn} do - clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.SimplePolicy]) - clear_config([:mrf, :transparency], true) - clear_config([:mrf, :transparency_exclusions], [{"other.site", "We don't want them to know"}]) + test "performs exclusions from MRF transparency data if configured", %{conn: conn} do + clear_config([:mrf, :transparency_exclusions], [ + {"other.site", "We don't want them to know"} + ]) - simple_config = %{"reject" => [{"example.com", ""}, {"other.site", ""}]} - clear_config(:mrf_simple, simple_config) + simple_config = %{"reject" => [{"example.com", ""}, {"other.site", ""}]} + clear_config(:mrf_simple, simple_config) - expected_config = %{"reject" => [%{"instance" => "example.com", "reason" => ""}]} + expected_config = %{"reject" => ["example.com"]} - response = - conn - |> get("/nodeinfo/2.1.json") - |> json_response(:ok) + response = + conn + |> get("/nodeinfo/2.1.json") + |> json_response(:ok) - assert response["metadata"]["federation"]["mrf_simple"] == expected_config - assert response["metadata"]["federation"]["exclusions"] == true + assert response["metadata"]["federation"]["mrf_simple"] == expected_config + assert response["metadata"]["federation"]["exclusions"] == true + end + + test "shows extra information in the mrf_simple_extra field for relevant entries", %{ + conn: conn + } do + simple_config = %{ + media_removal: [{"no.media", "LEEWWWDD >//<"}], + media_nsfw: [], + federated_timeline_removal: [{"no.ftl", ""}], + report_removal: [], + reject: [ + {"example.instance", "Some reason"}, + {"uwu.owo", "awoo to much"}, + {"no.reason", ""} + ], + followers_only: [], + accept: [], + avatar_removal: [], + banner_removal: [], + reject_deletes: [ + {"peak.me", "I want to peak at what they don't want me to see, eheh"} + ] + } + + clear_config(:mrf_simple, simple_config) + + clear_config([:mrf, :transparency_exclusions], [ + {"peak.me", "I don't want them to know"} + ]) + + expected_config = %{ + "media_removal" => %{ + "no.media" => %{"reason" => "LEEWWWDD >//<"} + }, + "reject" => %{ + "example.instance" => %{"reason" => "Some reason"}, + "uwu.owo" => %{"reason" => "awoo to much"} + } + } + + response = + conn + |> get("/nodeinfo/2.1.json") + |> json_response(:ok) + + assert response["metadata"]["federation"]["mrf_simple_info"] == expected_config + end end end From d9dfe3d451575b84e771411c1c702fc0ce22751f Mon Sep 17 00:00:00 2001 From: Ilja Date: Sat, 28 Nov 2020 10:34:31 +0100 Subject: [PATCH 16/16] quarantine instances info Added a new field in the nodeinfo called quarantined_instances_info This holds an object like `"quarantined_instances_info":{"quarantined_instances":{"quar.inst":{"reason":"whatever reason"}}}}` --- .../web/mastodon_api/views/instance_view.ex | 10 ++++- test/pleroma/web/node_info_test.exs | 44 ++++++++++++++----- 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/lib/pleroma/web/mastodon_api/views/instance_view.ex b/lib/pleroma/web/mastodon_api/views/instance_view.ex index ebddaba60..2804e908b 100644 --- a/lib/pleroma/web/mastodon_api/views/instance_view.ex +++ b/lib/pleroma/web/mastodon_api/views/instance_view.ex @@ -91,7 +91,15 @@ def federation do |> Map.merge(%{ quarantined_instances: quarantined - |> Enum.map(fn {instance, reason} -> %{"instance" => instance, "reason" => reason} end) + |> Enum.map(fn {instance, _reason} -> instance end) + }) + |> Map.merge(%{ + quarantined_instances_info: %{ + "quarantined_instances" => + quarantined + |> Enum.map(fn {instance, reason} -> {instance, %{"reason" => reason}} end) + |> Enum.into(%{}) + } }) else %{} diff --git a/test/pleroma/web/node_info_test.exs b/test/pleroma/web/node_info_test.exs index 952e26d4f..b2523119b 100644 --- a/test/pleroma/web/node_info_test.exs +++ b/test/pleroma/web/node_info_test.exs @@ -152,20 +152,42 @@ test "it shows default features flags", %{conn: conn} do ) end - test "it shows quarantined instances data if enabled", %{conn: conn} do - clear_config([:mrf, :transparency], true) + describe "Quarantined instances" do + setup do + clear_config([:mrf, :transparency], true) + quarantined_instances = [{"example.com", "reason to quarantine"}] + clear_config([:instance, :quarantined_instances], quarantined_instances) + end - quarantined_instances = [{"example.com", ""}] - clear_config([:instance, :quarantined_instances], quarantined_instances) + test "shows quarantined instances data if enabled", %{conn: conn} do + expected_config = ["example.com"] - expected_config = [%{"instance" => "example.com", "reason" => ""}] + response = + conn + |> get("/nodeinfo/2.1.json") + |> json_response(:ok) - response = - conn - |> get("/nodeinfo/2.1.json") - |> json_response(:ok) + assert response["metadata"]["federation"]["quarantined_instances"] == expected_config + end - assert response["metadata"]["federation"]["quarantined_instances"] == expected_config + test "shows extra information in the quarantined_info field for relevant entries", %{ + conn: conn + } do + clear_config([:mrf, :transparency], true) + + expected_config = %{ + "quarantined_instances" => %{ + "example.com" => %{"reason" => "reason to quarantine"} + } + } + + response = + conn + |> get("/nodeinfo/2.1.json") + |> json_response(:ok) + + assert response["metadata"]["federation"]["quarantined_instances_info"] == expected_config + end end describe "MRF SimplePolicy" do @@ -207,7 +229,7 @@ test "performs exclusions from MRF transparency data if configured", %{conn: con assert response["metadata"]["federation"]["exclusions"] == true end - test "shows extra information in the mrf_simple_extra field for relevant entries", %{ + test "shows extra information in the mrf_simple_info field for relevant entries", %{ conn: conn } do simple_config = %{