diff options
| -rw-r--r-- | lib/pleroma/web/activity_pub/mrf/ensure_re_prepended.ex | 17 | ||||
| -rw-r--r-- | lib/pleroma/web/activity_pub/mrf/no_placeholder_text_policy.ex | 12 | ||||
| -rw-r--r-- | lib/pleroma/web/activity_pub/mrf/normalize_markup.ex | 10 | ||||
| -rw-r--r-- | lib/pleroma/web/activity_pub/mrf/reject_non_public.ex | 38 | ||||
| -rw-r--r-- | lib/pleroma/web/activity_pub/mrf/tag_policy.ex | 53 | ||||
| -rw-r--r-- | lib/pleroma/web/activity_pub/mrf/user_allowlist_policy.ex (renamed from lib/pleroma/web/activity_pub/mrf/user_allowlist.ex) | 7 | ||||
| -rw-r--r-- | mix.lock | 1 | ||||
| -rw-r--r-- | test/web/activity_pub/mrf/ensure_re_prepended_test.exs | 82 | ||||
| -rw-r--r-- | test/web/activity_pub/mrf/no_placeholder_text_policy_test.exs | 37 | ||||
| -rw-r--r-- | test/web/activity_pub/mrf/normalize_markup_test.exs | 42 | ||||
| -rw-r--r-- | test/web/activity_pub/mrf/reject_non_public_test.exs | 105 | ||||
| -rw-r--r-- | test/web/activity_pub/mrf/tag_policy_test.exs | 123 | ||||
| -rw-r--r-- | test/web/activity_pub/mrf/user_allowlist_policy_test.exs | 36 | 
13 files changed, 495 insertions, 68 deletions
diff --git a/lib/pleroma/web/activity_pub/mrf/ensure_re_prepended.ex b/lib/pleroma/web/activity_pub/mrf/ensure_re_prepended.ex index 15d8514be..2d03df68a 100644 --- a/lib/pleroma/web/activity_pub/mrf/ensure_re_prepended.ex +++ b/lib/pleroma/web/activity_pub/mrf/ensure_re_prepended.ex @@ -9,8 +9,9 @@ defmodule Pleroma.Web.ActivityPub.MRF.EnsureRePrepended do    @behaviour Pleroma.Web.ActivityPub.MRF    @reply_prefix Regex.compile!("^re:[[:space:]]*", [:caseless]) +    def filter_by_summary( -        %{"summary" => parent_summary} = _parent, +        %{data: %{"summary" => parent_summary}} = _in_reply_to,          %{"summary" => child_summary} = child        )        when not is_nil(child_summary) and byte_size(child_summary) > 0 and @@ -24,17 +25,13 @@ defmodule Pleroma.Web.ActivityPub.MRF.EnsureRePrepended do      end    end -  def filter_by_summary(_parent, child), do: child - -  def filter(%{"type" => activity_type} = object) when activity_type == "Create" do -    child = object["object"] -    in_reply_to = Object.normalize(child["inReplyTo"]) +  def filter_by_summary(_in_reply_to, child), do: child +  def filter(%{"type" => "Create", "object" => child_object} = object) do      child = -      if(in_reply_to, -        do: filter_by_summary(in_reply_to.data, child), -        else: child -      ) +      child_object["inReplyTo"] +      |> Object.normalize(child_object["inReplyTo"]) +      |> filter_by_summary(child_object)      object = Map.put(object, "object", child) diff --git a/lib/pleroma/web/activity_pub/mrf/no_placeholder_text_policy.ex b/lib/pleroma/web/activity_pub/mrf/no_placeholder_text_policy.ex index f30fee0d5..86a48bda5 100644 --- a/lib/pleroma/web/activity_pub/mrf/no_placeholder_text_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/no_placeholder_text_policy.ex @@ -10,19 +10,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicy do    def filter(          %{            "type" => "Create", -          "object" => %{"content" => content, "attachment" => _attachment} = child_object +          "object" => %{"content" => content, "attachment" => _} = _child_object          } = object        )        when content in [".", "<p>.</p>"] do -    child_object = -      child_object -      |> Map.put("content", "") - -    object = -      object -      |> Map.put("object", child_object) - -    {:ok, object} +    {:ok, put_in(object, ["object", "content"], "")}    end    @impl true diff --git a/lib/pleroma/web/activity_pub/mrf/normalize_markup.ex b/lib/pleroma/web/activity_pub/mrf/normalize_markup.ex index 9c87c6963..c269d0f89 100644 --- a/lib/pleroma/web/activity_pub/mrf/normalize_markup.ex +++ b/lib/pleroma/web/activity_pub/mrf/normalize_markup.ex @@ -8,18 +8,14 @@ defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkup do    @behaviour Pleroma.Web.ActivityPub.MRF -  def filter(%{"type" => activity_type} = object) when activity_type == "Create" do +  def filter(%{"type" => "Create", "object" => child_object} = object) do      scrub_policy = Pleroma.Config.get([:mrf_normalize_markup, :scrub_policy]) -    child = object["object"] -      content = -      child["content"] +      child_object["content"]        |> HTML.filter_tags(scrub_policy) -    child = Map.put(child, "content", content) - -    object = Map.put(object, "object", child) +    object = put_in(object, ["object", "content"], content)      {:ok, object}    end diff --git a/lib/pleroma/web/activity_pub/mrf/reject_non_public.ex b/lib/pleroma/web/activity_pub/mrf/reject_non_public.ex index ea3df1b4d..da13fd7c7 100644 --- a/lib/pleroma/web/activity_pub/mrf/reject_non_public.ex +++ b/lib/pleroma/web/activity_pub/mrf/reject_non_public.ex @@ -3,46 +3,42 @@  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Web.ActivityPub.MRF.RejectNonPublic do -  alias Pleroma.User    @moduledoc "Rejects non-public (followers-only, direct) activities" + +  alias Pleroma.Config +  alias Pleroma.User +    @behaviour Pleroma.Web.ActivityPub.MRF +  @public "https://www.w3.org/ns/activitystreams#Public" +    @impl true    def filter(%{"type" => "Create"} = object) do      user = User.get_cached_by_ap_id(object["actor"]) -    public = "https://www.w3.org/ns/activitystreams#Public"      # Determine visibility      visibility =        cond do -        public in object["to"] -> "public" -        public in object["cc"] -> "unlisted" +        @public in object["to"] -> "public" +        @public in object["cc"] -> "unlisted"          user.follower_address in object["to"] -> "followers"          true -> "direct"        end -    policy = Pleroma.Config.get(:mrf_rejectnonpublic) +    policy = Config.get(:mrf_rejectnonpublic) + +    cond do +      visibility in ["public", "unlisted"] -> +        {:ok, object} -    case visibility do -      "public" -> +      visibility == "followers" and Keyword.get(policy, :allow_followersonly) ->          {:ok, object} -      "unlisted" -> +      visibility == "direct" and Keyword.get(policy, :allow_direct) ->          {:ok, object} -      "followers" -> -        with true <- Keyword.get(policy, :allow_followersonly) do -          {:ok, object} -        else -          _e -> {:reject, nil} -        end - -      "direct" -> -        with true <- Keyword.get(policy, :allow_direct) do -          {:ok, object} -        else -          _e -> {:reject, nil} -        end +      true -> +        {:reject, nil}      end    end diff --git a/lib/pleroma/web/activity_pub/mrf/tag_policy.ex b/lib/pleroma/web/activity_pub/mrf/tag_policy.ex index 6683b8d8e..b42c4ed76 100644 --- a/lib/pleroma/web/activity_pub/mrf/tag_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/tag_policy.ex @@ -19,12 +19,17 @@ defmodule Pleroma.Web.ActivityPub.MRF.TagPolicy do       - `mrf_tag:disable-any-subscription`: Reject any follow requests    """ +  @public "https://www.w3.org/ns/activitystreams#Public" +    defp get_tags(%User{tags: tags}) when is_list(tags), do: tags    defp get_tags(_), do: []    defp process_tag(           "mrf_tag:media-force-nsfw", -         %{"type" => "Create", "object" => %{"attachment" => child_attachment} = object} = message +         %{ +           "type" => "Create", +           "object" => %{"attachment" => child_attachment} = object +         } = message         )         when length(child_attachment) > 0 do      tags = (object["tag"] || []) ++ ["nsfw"] @@ -41,7 +46,10 @@ defmodule Pleroma.Web.ActivityPub.MRF.TagPolicy do    defp process_tag(           "mrf_tag:media-strip", -         %{"type" => "Create", "object" => %{"attachment" => child_attachment} = object} = message +         %{ +           "type" => "Create", +           "object" => %{"attachment" => child_attachment} = object +         } = message         )         when length(child_attachment) > 0 do      object = Map.delete(object, "attachment") @@ -52,19 +60,22 @@ defmodule Pleroma.Web.ActivityPub.MRF.TagPolicy do    defp process_tag(           "mrf_tag:force-unlisted", -         %{"type" => "Create", "to" => to, "cc" => cc, "actor" => actor} = message +         %{ +           "type" => "Create", +           "to" => to, +           "cc" => cc, +           "actor" => actor, +           "object" => object +         } = message         ) do      user = User.get_cached_by_ap_id(actor) -    if Enum.member?(to, "https://www.w3.org/ns/activitystreams#Public") do -      to = -        List.delete(to, "https://www.w3.org/ns/activitystreams#Public") ++ [user.follower_address] - -      cc = -        List.delete(cc, user.follower_address) ++ ["https://www.w3.org/ns/activitystreams#Public"] +    if Enum.member?(to, @public) do +      to = List.delete(to, @public) ++ [user.follower_address] +      cc = List.delete(cc, user.follower_address) ++ [@public]        object = -        message["object"] +        object          |> Map.put("to", to)          |> Map.put("cc", cc) @@ -82,19 +93,22 @@ defmodule Pleroma.Web.ActivityPub.MRF.TagPolicy do    defp process_tag(           "mrf_tag:sandbox", -         %{"type" => "Create", "to" => to, "cc" => cc, "actor" => actor} = message +         %{ +           "type" => "Create", +           "to" => to, +           "cc" => cc, +           "actor" => actor, +           "object" => object +         } = message         ) do      user = User.get_cached_by_ap_id(actor) -    if Enum.member?(to, "https://www.w3.org/ns/activitystreams#Public") or -         Enum.member?(cc, "https://www.w3.org/ns/activitystreams#Public") do -      to = -        List.delete(to, "https://www.w3.org/ns/activitystreams#Public") ++ [user.follower_address] - -      cc = List.delete(cc, "https://www.w3.org/ns/activitystreams#Public") +    if Enum.member?(to, @public) or Enum.member?(cc, @public) do +      to = List.delete(to, @public) ++ [user.follower_address] +      cc = List.delete(cc, @public)        object = -        message["object"] +        object          |> Map.put("to", to)          |> Map.put("cc", cc) @@ -123,7 +137,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.TagPolicy do      end    end -  defp process_tag("mrf_tag:disable-any-subscription", %{"type" => "Follow"}), do: {:reject, nil} +  defp process_tag("mrf_tag:disable-any-subscription", %{"type" => "Follow"}), +    do: {:reject, nil}    defp process_tag(_, message), do: {:ok, message} diff --git a/lib/pleroma/web/activity_pub/mrf/user_allowlist.ex b/lib/pleroma/web/activity_pub/mrf/user_allowlist_policy.ex index 47663414a..e35d2c422 100644 --- a/lib/pleroma/web/activity_pub/mrf/user_allowlist.ex +++ b/lib/pleroma/web/activity_pub/mrf/user_allowlist_policy.ex @@ -21,7 +21,12 @@ defmodule Pleroma.Web.ActivityPub.MRF.UserAllowListPolicy do    @impl true    def filter(%{"actor" => actor} = object) do      actor_info = URI.parse(actor) -    allow_list = Config.get([:mrf_user_allowlist, String.to_atom(actor_info.host)], []) + +    allow_list = +      Config.get( +        [:mrf_user_allowlist, String.to_atom(actor_info.host)], +        [] +      )      filter_by_list(object, allow_list)    end @@ -76,6 +76,7 @@    "ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm"},    "recon": {:git, "https://github.com/ferd/recon.git", "75d70c7c08926d2f24f1ee6de14ee50fe8a52763", [tag: "2.4.0"]},    "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"}, +  "stream_data": {:hex, :stream_data, "0.4.3", "62aafd870caff0849a5057a7ec270fad0eb86889f4d433b937d996de99e3db25", [:mix], [], "hexpm"},    "swoosh": {:hex, :swoosh, "0.20.0", "9a6c13822c9815993c03b6f8fccc370fcffb3c158d9754f67b1fdee6b3a5d928", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.12", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 1.1", [hex: :mime, repo: "hexpm", optional: false]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm"},    "syslog": {:git, "https://github.com/Vagabond/erlang-syslog.git", "4a6c6f2c996483e86c1320e9553f91d337bcb6aa", [tag: "1.0.5"]},    "telemetry": {:hex, :telemetry, "0.4.0", "8339bee3fa8b91cb84d14c2935f8ecf399ccd87301ad6da6b71c09553834b2ab", [:rebar3], [], "hexpm"}, diff --git a/test/web/activity_pub/mrf/ensure_re_prepended_test.exs b/test/web/activity_pub/mrf/ensure_re_prepended_test.exs new file mode 100644 index 000000000..dbc8b9e80 --- /dev/null +++ b/test/web/activity_pub/mrf/ensure_re_prepended_test.exs @@ -0,0 +1,82 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ActivityPub.MRF.EnsureRePrependedTest do +  use Pleroma.DataCase + +  alias Pleroma.Activity +  alias Pleroma.Object +  alias Pleroma.Web.ActivityPub.MRF.EnsureRePrepended + +  describe "rewrites summary" do +    test "it adds `re:` to summary object when child summary and parent summary equal" do +      message = %{ +        "type" => "Create", +        "object" => %{ +          "summary" => "object-summary", +          "inReplyTo" => %Activity{object: %Object{data: %{"summary" => "object-summary"}}} +        } +      } + +      assert {:ok, res} = EnsureRePrepended.filter(message) +      assert res["object"]["summary"] == "re: object-summary" +    end + +    test "it adds `re:` to summary object when child summary containts re-subject of parent summary " do +      message = %{ +        "type" => "Create", +        "object" => %{ +          "summary" => "object-summary", +          "inReplyTo" => %Activity{object: %Object{data: %{"summary" => "re: object-summary"}}} +        } +      } + +      assert {:ok, res} = EnsureRePrepended.filter(message) +      assert res["object"]["summary"] == "re: object-summary" +    end +  end + +  describe "skip filter" do +    test "it skip if type isn't 'Create'" do +      message = %{ +        "type" => "Annotation", +        "object" => %{"summary" => "object-summary"} +      } + +      assert {:ok, res} = EnsureRePrepended.filter(message) +      assert res == message +    end + +    test "it skip if summary is empty" do +      message = %{ +        "type" => "Create", +        "object" => %{ +          "inReplyTo" => %Activity{object: %Object{data: %{"summary" => "summary"}}} +        } +      } + +      assert {:ok, res} = EnsureRePrepended.filter(message) +      assert res == message +    end + +    test "it skip if inReplyTo is empty" do +      message = %{"type" => "Create", "object" => %{"summary" => "summary"}} +      assert {:ok, res} = EnsureRePrepended.filter(message) +      assert res == message +    end + +    test "it skip if parent and child summary isn't equal" do +      message = %{ +        "type" => "Create", +        "object" => %{ +          "summary" => "object-summary", +          "inReplyTo" => %Activity{object: %Object{data: %{"summary" => "summary"}}} +        } +      } + +      assert {:ok, res} = EnsureRePrepended.filter(message) +      assert res == message +    end +  end +end diff --git a/test/web/activity_pub/mrf/no_placeholder_text_policy_test.exs b/test/web/activity_pub/mrf/no_placeholder_text_policy_test.exs new file mode 100644 index 000000000..63ed71129 --- /dev/null +++ b/test/web/activity_pub/mrf/no_placeholder_text_policy_test.exs @@ -0,0 +1,37 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicyTest do +  use Pleroma.DataCase +  alias Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicy + +  test "it clears content object" do +    message = %{ +      "type" => "Create", +      "object" => %{"content" => ".", "attachment" => "image"} +    } + +    assert {:ok, res} = NoPlaceholderTextPolicy.filter(message) +    assert res["object"]["content"] == "" + +    message = put_in(message, ["object", "content"], "<p>.</p>") +    assert {:ok, res} = NoPlaceholderTextPolicy.filter(message) +    assert res["object"]["content"] == "" +  end + +  @messages [ +    %{ +      "type" => "Create", +      "object" => %{"content" => "test", "attachment" => "image"} +    }, +    %{"type" => "Create", "object" => %{"content" => "."}}, +    %{"type" => "Create", "object" => %{"content" => "<p>.</p>"}} +  ] +  test "it skips filter" do +    Enum.each(@messages, fn message -> +      assert {:ok, res} = NoPlaceholderTextPolicy.filter(message) +      assert res == message +    end) +  end +end diff --git a/test/web/activity_pub/mrf/normalize_markup_test.exs b/test/web/activity_pub/mrf/normalize_markup_test.exs new file mode 100644 index 000000000..3916a1f35 --- /dev/null +++ b/test/web/activity_pub/mrf/normalize_markup_test.exs @@ -0,0 +1,42 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkupTest do +  use Pleroma.DataCase +  alias Pleroma.Web.ActivityPub.MRF.NormalizeMarkup + +  @html_sample """ +  <b>this is in bold</b> +  <p>this is a paragraph</p> +  this is a linebreak<br /> +  this is a link with allowed "rel" attribute: <a href="http://example.com/" rel="tag">example.com</a> +  this is a link with not allowed "rel" attribute: <a href="http://example.com/" rel="tag noallowed">example.com</a> +  this is an image: <img src="http://example.com/image.jpg"><br /> +  <script>alert('hacked')</script> +  """ + +  test "it filter html tags" do +    expected = """ +    <b>this is in bold</b> +    <p>this is a paragraph</p> +    this is a linebreak<br /> +    this is a link with allowed "rel" attribute: <a href="http://example.com/" rel="tag">example.com</a> +    this is a link with not allowed "rel" attribute: <a href="http://example.com/">example.com</a> +    this is an image: <img src="http://example.com/image.jpg" /><br /> +    alert('hacked') +    """ + +    message = %{"type" => "Create", "object" => %{"content" => @html_sample}} + +    assert {:ok, res} = NormalizeMarkup.filter(message) +    assert res["object"]["content"] == expected +  end + +  test "it skips filter if type isn't `Create`" do +    message = %{"type" => "Note", "object" => %{}} + +    assert {:ok, res} = NormalizeMarkup.filter(message) +    assert res == message +  end +end diff --git a/test/web/activity_pub/mrf/reject_non_public_test.exs b/test/web/activity_pub/mrf/reject_non_public_test.exs new file mode 100644 index 000000000..fdf6b245e --- /dev/null +++ b/test/web/activity_pub/mrf/reject_non_public_test.exs @@ -0,0 +1,105 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ActivityPub.MRF.RejectNonPublicTest do +  use Pleroma.DataCase +  import Pleroma.Factory + +  alias Pleroma.Web.ActivityPub.MRF.RejectNonPublic + +  setup do +    policy = Pleroma.Config.get([:mrf_rejectnonpublic]) +    on_exit(fn -> Pleroma.Config.put([:mrf_rejectnonpublic], policy) end) + +    :ok +  end + +  describe "public message" do +    test "it's allowed when address is public" do +      actor = insert(:user, follower_address: "test-address") + +      message = %{ +        "actor" => actor.ap_id, +        "to" => ["https://www.w3.org/ns/activitystreams#Public"], +        "cc" => ["https://www.w3.org/ns/activitystreams#Publid"], +        "type" => "Create" +      } + +      assert {:ok, message} = RejectNonPublic.filter(message) +    end + +    test "it's allowed when cc address contain public address" do +      actor = insert(:user, follower_address: "test-address") + +      message = %{ +        "actor" => actor.ap_id, +        "to" => ["https://www.w3.org/ns/activitystreams#Public"], +        "cc" => ["https://www.w3.org/ns/activitystreams#Publid"], +        "type" => "Create" +      } + +      assert {:ok, message} = RejectNonPublic.filter(message) +    end +  end + +  describe "followers message" do +    test "it's allowed when addrer of message in the follower addresses of user and it enabled in config" do +      actor = insert(:user, follower_address: "test-address") + +      message = %{ +        "actor" => actor.ap_id, +        "to" => ["test-address"], +        "cc" => ["https://www.w3.org/ns/activitystreams#Publid"], +        "type" => "Create" +      } + +      Pleroma.Config.put([:mrf_rejectnonpublic, :allow_followersonly], true) +      assert {:ok, message} = RejectNonPublic.filter(message) +    end + +    test "it's rejected when addrer of message in the follower addresses of user and it disabled in config" do +      actor = insert(:user, follower_address: "test-address") + +      message = %{ +        "actor" => actor.ap_id, +        "to" => ["test-address"], +        "cc" => ["https://www.w3.org/ns/activitystreams#Publid"], +        "type" => "Create" +      } + +      Pleroma.Config.put([:mrf_rejectnonpublic, :allow_followersonly], false) +      assert {:reject, nil} = RejectNonPublic.filter(message) +    end +  end + +  describe "direct message" do +    test "it's allows when direct messages are allow" do +      actor = insert(:user) + +      message = %{ +        "actor" => actor.ap_id, +        "to" => ["https://www.w3.org/ns/activitystreams#Publid"], +        "cc" => ["https://www.w3.org/ns/activitystreams#Publid"], +        "type" => "Create" +      } + +      Pleroma.Config.put([:mrf_rejectnonpublic, :allow_direct], true) +      assert {:ok, message} = RejectNonPublic.filter(message) +    end + +    test "it's reject when direct messages aren't allow" do +      actor = insert(:user) + +      message = %{ +        "actor" => actor.ap_id, +        "to" => ["https://www.w3.org/ns/activitystreams#Publid~~~"], +        "cc" => ["https://www.w3.org/ns/activitystreams#Publid"], +        "type" => "Create" +      } + +      Pleroma.Config.put([:mrf_rejectnonpublic, :allow_direct], false) +      assert {:reject, nil} = RejectNonPublic.filter(message) +    end +  end +end diff --git a/test/web/activity_pub/mrf/tag_policy_test.exs b/test/web/activity_pub/mrf/tag_policy_test.exs new file mode 100644 index 000000000..4aa35311e --- /dev/null +++ b/test/web/activity_pub/mrf/tag_policy_test.exs @@ -0,0 +1,123 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ActivityPub.MRF.TagPolicyTest do +  use Pleroma.DataCase +  import Pleroma.Factory + +  alias Pleroma.Web.ActivityPub.MRF.TagPolicy +  @public "https://www.w3.org/ns/activitystreams#Public" + +  describe "mrf_tag:disable-any-subscription" do +    test "rejects message" do +      actor = insert(:user, tags: ["mrf_tag:disable-any-subscription"]) +      message = %{"object" => actor.ap_id, "type" => "Follow"} +      assert {:reject, nil} = TagPolicy.filter(message) +    end +  end + +  describe "mrf_tag:disable-remote-subscription" do +    test "rejects non-local follow requests" do +      actor = insert(:user, tags: ["mrf_tag:disable-remote-subscription"]) +      follower = insert(:user, tags: ["mrf_tag:disable-remote-subscription"], local: false) +      message = %{"object" => actor.ap_id, "type" => "Follow", "actor" => follower.ap_id} +      assert {:reject, nil} = TagPolicy.filter(message) +    end + +    test "allows non-local follow requests" do +      actor = insert(:user, tags: ["mrf_tag:disable-remote-subscription"]) +      follower = insert(:user, tags: ["mrf_tag:disable-remote-subscription"], local: true) +      message = %{"object" => actor.ap_id, "type" => "Follow", "actor" => follower.ap_id} +      assert {:ok, message} = TagPolicy.filter(message) +    end +  end + +  describe "mrf_tag:sandbox" do +    test "removes from public timelines" do +      actor = insert(:user, tags: ["mrf_tag:sandbox"]) + +      message = %{ +        "actor" => actor.ap_id, +        "type" => "Create", +        "object" => %{}, +        "to" => [@public, "f"], +        "cc" => [@public, "d"] +      } + +      except_message = %{ +        "actor" => actor.ap_id, +        "type" => "Create", +        "object" => %{"to" => ["f", actor.follower_address], "cc" => ["d"]}, +        "to" => ["f", actor.follower_address], +        "cc" => ["d"] +      } + +      assert TagPolicy.filter(message) == {:ok, except_message} +    end +  end + +  describe "mrf_tag:force-unlisted" do +    test "removes from the federated timeline" do +      actor = insert(:user, tags: ["mrf_tag:force-unlisted"]) + +      message = %{ +        "actor" => actor.ap_id, +        "type" => "Create", +        "object" => %{}, +        "to" => [@public, "f"], +        "cc" => [actor.follower_address, "d"] +      } + +      except_message = %{ +        "actor" => actor.ap_id, +        "type" => "Create", +        "object" => %{"to" => ["f", actor.follower_address], "cc" => ["d", @public]}, +        "to" => ["f", actor.follower_address], +        "cc" => ["d", @public] +      } + +      assert TagPolicy.filter(message) == {:ok, except_message} +    end +  end + +  describe "mrf_tag:media-strip" do +    test "removes attachments" do +      actor = insert(:user, tags: ["mrf_tag:media-strip"]) + +      message = %{ +        "actor" => actor.ap_id, +        "type" => "Create", +        "object" => %{"attachment" => ["file1"]} +      } + +      except_message = %{ +        "actor" => actor.ap_id, +        "type" => "Create", +        "object" => %{} +      } + +      assert TagPolicy.filter(message) == {:ok, except_message} +    end +  end + +  describe "mrf_tag:media-force-nsfw" do +    test "Mark as sensitive on presence of attachments" do +      actor = insert(:user, tags: ["mrf_tag:media-force-nsfw"]) + +      message = %{ +        "actor" => actor.ap_id, +        "type" => "Create", +        "object" => %{"tag" => ["test"], "attachment" => ["file1"]} +      } + +      except_message = %{ +        "actor" => actor.ap_id, +        "type" => "Create", +        "object" => %{"tag" => ["test", "nsfw"], "attachment" => ["file1"], "sensitive" => true} +      } + +      assert TagPolicy.filter(message) == {:ok, except_message} +    end +  end +end diff --git a/test/web/activity_pub/mrf/user_allowlist_policy_test.exs b/test/web/activity_pub/mrf/user_allowlist_policy_test.exs new file mode 100644 index 000000000..6519e2398 --- /dev/null +++ b/test/web/activity_pub/mrf/user_allowlist_policy_test.exs @@ -0,0 +1,36 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only +defmodule Pleroma.Web.ActivityPub.MRF.UserAllowListPolicyTest do +  use Pleroma.DataCase +  import Pleroma.Factory + +  alias Pleroma.Web.ActivityPub.MRF.UserAllowListPolicy + +  setup do +    policy = Pleroma.Config.get([:mrf_user_allowlist]) || [] +    on_exit(fn -> Pleroma.Config.put([:mrf_user_allowlist], policy) end) + +    :ok +  end + +  test "pass filter if allow list is empty" do +    actor = insert(:user) +    message = %{"actor" => actor.ap_id} +    assert UserAllowListPolicy.filter(message) == {:ok, message} +  end + +  test "pass filter if allow list isn't empty and user in allow list" do +    actor = insert(:user) +    Pleroma.Config.put([:mrf_user_allowlist, :localhost], [actor.ap_id, "test-ap-id"]) +    message = %{"actor" => actor.ap_id} +    assert UserAllowListPolicy.filter(message) == {:ok, message} +  end + +  test "rejected if allow list isn't empty and user not in allow list" do +    actor = insert(:user) +    Pleroma.Config.put([:mrf_user_allowlist, :localhost], ["test-ap-id"]) +    message = %{"actor" => actor.ap_id} +    assert UserAllowListPolicy.filter(message) == {:reject, nil} +  end +end  | 
