Page MenuHomePhorge

No OneTemporary

Size
30 KB
Referenced Files
None
Subscribers
None
diff --git a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex
index c0c7f3806..829ddeaea 100644
--- a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex
@@ -1,369 +1,370 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
@moduledoc "Filter activities depending on their origin instance"
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
alias Pleroma.Config
alias Pleroma.FollowingRelationship
alias Pleroma.User
alias Pleroma.Web.ActivityPub.MRF
require Pleroma.Constants
defp check_accept(%{host: actor_host} = _actor_info, object) do
accepts =
instance_list(:accept)
|> MRF.subdomains_regex()
cond do
accepts == [] -> {:ok, object}
actor_host == Config.get([Pleroma.Web.Endpoint, :url, :host]) -> {:ok, object}
MRF.subdomain_match?(accepts, actor_host) -> {:ok, object}
true -> {:reject, "[SimplePolicy] host not in accept list"}
end
end
defp check_reject(%{host: actor_host} = _actor_info, object) do
rejects =
instance_list(:reject)
|> MRF.subdomains_regex()
if MRF.subdomain_match?(rejects, actor_host) do
{:reject, "[SimplePolicy] host in reject list"}
else
{:ok, object}
end
end
defp check_media_removal(
%{host: actor_host} = _actor_info,
- %{"type" => "Create", "object" => %{"attachment" => child_attachment}} = object
+ %{"type" => type, "object" => %{"attachment" => child_attachment}} = object
)
- when length(child_attachment) > 0 do
+ when length(child_attachment) > 0 and type in ["Create", "Update"] do
media_removal =
instance_list(:media_removal)
|> MRF.subdomains_regex()
object =
if MRF.subdomain_match?(media_removal, actor_host) do
child_object = Map.delete(object["object"], "attachment")
Map.put(object, "object", child_object)
else
object
end
{:ok, object}
end
defp check_media_removal(_actor_info, object), do: {:ok, object}
defp check_media_nsfw(
%{host: actor_host} = _actor_info,
%{
- "type" => "Create",
+ "type" => type,
"object" => %{} = _child_object
} = object
- ) do
+ )
+ when type in ["Create", "Update"] do
media_nsfw =
instance_list(:media_nsfw)
|> MRF.subdomains_regex()
object =
if MRF.subdomain_match?(media_nsfw, actor_host) do
Kernel.put_in(object, ["object", "sensitive"], true)
else
object
end
{:ok, object}
end
defp check_media_nsfw(_actor_info, object), do: {:ok, object}
defp check_ftl_removal(%{host: actor_host} = _actor_info, object) do
timeline_removal =
instance_list(:federated_timeline_removal)
|> MRF.subdomains_regex()
object =
with true <- MRF.subdomain_match?(timeline_removal, actor_host),
user <- User.get_cached_by_ap_id(object["actor"]),
true <- Pleroma.Constants.as_public() in object["to"] do
to = List.delete(object["to"], Pleroma.Constants.as_public()) ++ [user.follower_address]
cc = List.delete(object["cc"], user.follower_address) ++ [Pleroma.Constants.as_public()]
object
|> Map.put("to", to)
|> Map.put("cc", cc)
else
_ -> object
end
{:ok, object}
end
defp intersection(list1, list2) do
list1 -- list1 -- list2
end
defp check_followers_only(%{host: actor_host} = _actor_info, object) do
followers_only =
instance_list(:followers_only)
|> MRF.subdomains_regex()
object =
with true <- MRF.subdomain_match?(followers_only, actor_host),
user <- User.get_cached_by_ap_id(object["actor"]) do
# Don't use Map.get/3 intentionally, these must not be nil
fixed_to = object["to"] || []
fixed_cc = object["cc"] || []
to = FollowingRelationship.followers_ap_ids(user, fixed_to)
cc = FollowingRelationship.followers_ap_ids(user, fixed_cc)
object
|> Map.put("to", intersection([user.follower_address | to], fixed_to))
|> Map.put("cc", intersection([user.follower_address | cc], fixed_cc))
else
_ -> object
end
{:ok, object}
end
defp check_report_removal(%{host: actor_host} = _actor_info, %{"type" => "Flag"} = object) do
report_removal =
instance_list(:report_removal)
|> MRF.subdomains_regex()
if MRF.subdomain_match?(report_removal, actor_host) do
{:reject, "[SimplePolicy] host in report_removal list"}
else
{:ok, object}
end
end
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 =
instance_list(:avatar_removal)
|> MRF.subdomains_regex()
if MRF.subdomain_match?(avatar_removal, actor_host) do
{:ok, Map.delete(object, "icon")}
else
{:ok, object}
end
end
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 =
instance_list(:banner_removal)
|> MRF.subdomains_regex()
if MRF.subdomain_match?(banner_removal, actor_host) do
{:ok, Map.delete(object, "image")}
else
{:ok, object}
end
end
defp check_banner_removal(_actor_info, object), do: {:ok, object}
defp check_object(%{"object" => object} = activity) do
with {:ok, _object} <- filter(object) do
{:ok, activity}
end
end
defp check_object(object), do: {:ok, object}
defp instance_list(config_key) do
Config.get([:mrf_simple, config_key])
|> MRF.instance_list_from_tuples()
end
@impl true
def filter(%{"type" => "Delete", "actor" => actor} = object) do
%{host: actor_host} = URI.parse(actor)
reject_deletes =
instance_list(:reject_deletes)
|> MRF.subdomains_regex()
if MRF.subdomain_match?(reject_deletes, actor_host) do
{:reject, "[SimplePolicy] host in reject_deletes list"}
else
{:ok, object}
end
end
@impl true
def filter(%{"actor" => actor} = object) do
actor_info = URI.parse(actor)
with {:ok, object} <- check_accept(actor_info, object),
{:ok, object} <- check_reject(actor_info, object),
{:ok, object} <- check_media_removal(actor_info, object),
{:ok, object} <- check_media_nsfw(actor_info, object),
{:ok, object} <- check_ftl_removal(actor_info, object),
{:ok, object} <- check_followers_only(actor_info, object),
{:ok, object} <- check_report_removal(actor_info, object),
{:ok, object} <- check_object(object) do
{:ok, object}
else
{:reject, nil} -> {:reject, "[SimplePolicy]"}
{:reject, _} = e -> e
_ -> {:reject, "[SimplePolicy]"}
end
end
def filter(%{"id" => actor, "type" => obj_type} = object)
when obj_type in ["Application", "Group", "Organization", "Person", "Service"] do
actor_info = URI.parse(actor)
with {:ok, object} <- check_accept(actor_info, object),
{:ok, object} <- check_reject(actor_info, object),
{:ok, object} <- check_avatar_removal(actor_info, object),
{:ok, object} <- check_banner_removal(actor_info, object) do
{:ok, object}
else
{:reject, nil} -> {:reject, "[SimplePolicy]"}
{:reject, _} = e -> e
_ -> {:reject, "[SimplePolicy]"}
end
end
def filter(object) when is_binary(object) do
uri = URI.parse(object)
with {:ok, object} <- check_accept(uri, object),
{:ok, object} <- check_reject(uri, object) do
{:ok, object}
else
{:reject, nil} -> {:reject, "[SimplePolicy]"}
{:reject, _} = e -> e
_ -> {:reject, "[SimplePolicy]"}
end
end
def filter(object), do: {:ok, object}
@impl true
def describe do
exclusions = Config.get([:mrf, :transparency_exclusions]) |> MRF.instance_list_from_tuples()
mrf_simple_excluded =
Config.get(:mrf_simple)
|> Enum.map(fn {rule, instances} ->
{rule, Enum.reject(instances, fn {host, _} -> host in exclusions end)}
end)
mrf_simple =
mrf_simple_excluded
|> Enum.map(fn {rule, instances} ->
{rule, Enum.map(instances, fn {host, _} -> host end)}
end)
|> Map.new()
# This is for backwards compatibility. We originally didn't sent
# extra info like a reason why an instance was rejected/quarantined/etc.
# Because we didn't want to break backwards compatibility it was decided
# to add an extra "info" key.
mrf_simple_info =
mrf_simple_excluded
|> Enum.map(fn {rule, instances} ->
{rule, Enum.reject(instances, fn {_, reason} -> reason == "" end)}
end)
|> Enum.reject(fn {_, instances} -> instances == [] end)
|> Enum.map(fn {rule, instances} ->
instances =
instances
|> Enum.map(fn {host, reason} -> {host, %{"reason" => reason}} end)
|> Map.new()
{rule, instances}
end)
|> Map.new()
{:ok, %{mrf_simple: mrf_simple, mrf_simple_info: mrf_simple_info}}
end
@impl true
def config_description do
%{
key: :mrf_simple,
related_policy: "Pleroma.Web.ActivityPub.MRF.SimplePolicy",
label: "MRF Simple",
description: "Simple ingress policies",
children:
[
%{
key: :media_removal,
description:
"List of instances to strip media attachments from and the reason for doing so"
},
%{
key: :media_nsfw,
label: "Media NSFW",
description:
"List of instances to tag all media as NSFW (sensitive) from and the reason for doing so"
},
%{
key: :federated_timeline_removal,
description:
"List of instances to remove from the Federated (aka The Whole Known Network) Timeline and the reason for doing so"
},
%{
key: :reject,
description:
"List of instances to reject activities from (except deletes) and the reason for doing so"
},
%{
key: :accept,
description:
"List of instances to only accept activities from (except deletes) and the reason for doing so"
},
%{
key: :followers_only,
description:
"Force posts from the given instances to be visible by followers only and the reason for doing so"
},
%{
key: :report_removal,
description: "List of instances to reject reports from and the reason for doing so"
},
%{
key: :avatar_removal,
description: "List of instances to strip avatars from and the reason for doing so"
},
%{
key: :banner_removal,
description: "List of instances to strip banners from and the reason for doing so"
},
%{
key: :reject_deletes,
description: "List of instances to reject deletions from and the reason for doing so"
}
]
|> Enum.map(fn setting ->
Map.merge(
setting,
%{
type: {:list, :tuple},
key_placeholder: "instance",
value_placeholder: "reason",
suggestions: [{"example.com", "Some reason"}, {"*.example.com", "Another reason"}]
}
)
end)
}
end
end
diff --git a/test/pleroma/web/activity_pub/mrf/simple_policy_test.exs b/test/pleroma/web/activity_pub/mrf/simple_policy_test.exs
index 674b506c3..57fc00af5 100644
--- a/test/pleroma/web/activity_pub/mrf/simple_policy_test.exs
+++ b/test/pleroma/web/activity_pub/mrf/simple_policy_test.exs
@@ -1,561 +1,579 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
use Pleroma.DataCase
import Pleroma.Factory
alias Pleroma.Web.ActivityPub.MRF.SimplePolicy
alias Pleroma.Web.CommonAPI
setup do:
clear_config(:mrf_simple,
media_removal: [],
media_nsfw: [],
federated_timeline_removal: [],
report_removal: [],
reject: [],
followers_only: [],
accept: [],
avatar_removal: [],
banner_removal: [],
reject_deletes: []
)
describe "when :media_removal" do
test "is empty" do
clear_config([:mrf_simple, :media_removal], [])
media_message = build_media_message()
local_message = build_local_message()
assert SimplePolicy.filter(media_message) == {:ok, media_message}
assert SimplePolicy.filter(local_message) == {:ok, local_message}
end
test "has a matching host" do
clear_config([:mrf_simple, :media_removal], [{"remote.instance", "Some reason"}])
media_message = build_media_message()
local_message = build_local_message()
assert SimplePolicy.filter(media_message) ==
{:ok,
media_message
|> Map.put("object", Map.delete(media_message["object"], "attachment"))}
assert SimplePolicy.filter(local_message) == {:ok, local_message}
end
test "match with wildcard domain" do
clear_config([:mrf_simple, :media_removal], [{"*.remote.instance", "Whatever reason"}])
media_message = build_media_message()
local_message = build_local_message()
assert SimplePolicy.filter(media_message) ==
{:ok,
media_message
|> Map.put("object", Map.delete(media_message["object"], "attachment"))}
assert SimplePolicy.filter(local_message) == {:ok, local_message}
end
+
+ test "works with Updates" do
+ clear_config([:mrf_simple, :media_removal], [{"remote.instance", "Some reason"}])
+ media_message = build_media_message(type: "Update")
+
+ assert SimplePolicy.filter(media_message) ==
+ {:ok,
+ media_message
+ |> Map.put("object", Map.delete(media_message["object"], "attachment"))}
+ end
end
describe "when :media_nsfw" do
test "is empty" do
clear_config([:mrf_simple, :media_nsfw], [])
media_message = build_media_message()
local_message = build_local_message()
assert SimplePolicy.filter(media_message) == {:ok, media_message}
assert SimplePolicy.filter(local_message) == {:ok, local_message}
end
test "has a matching host" do
clear_config([:mrf_simple, :media_nsfw], [{"remote.instance", "Whetever"}])
media_message = build_media_message()
local_message = build_local_message()
assert SimplePolicy.filter(media_message) ==
{:ok, put_in(media_message, ["object", "sensitive"], true)}
assert SimplePolicy.filter(local_message) == {:ok, local_message}
end
test "match with wildcard domain" do
clear_config([:mrf_simple, :media_nsfw], [{"*.remote.instance", "yeah yeah"}])
media_message = build_media_message()
local_message = build_local_message()
assert SimplePolicy.filter(media_message) ==
{:ok, put_in(media_message, ["object", "sensitive"], true)}
assert SimplePolicy.filter(local_message) == {:ok, local_message}
end
+
+ test "works with Updates" do
+ clear_config([:mrf_simple, :media_nsfw], [{"remote.instance", "Whetever"}])
+ media_message = build_media_message(type: "Update")
+
+ assert SimplePolicy.filter(media_message) ==
+ {:ok, put_in(media_message, ["object", "sensitive"], true)}
+ end
end
- defp build_media_message do
+ defp build_media_message(opts \\ []) do
%{
"actor" => "https://remote.instance/users/bob",
- "type" => "Create",
+ "type" => opts[:type] || "Create",
"object" => %{
"attachment" => [%{}],
"tag" => ["foo"],
"sensitive" => false
}
}
end
describe "when :report_removal" do
test "is empty" do
clear_config([:mrf_simple, :report_removal], [])
report_message = build_report_message()
local_message = build_local_message()
assert SimplePolicy.filter(report_message) == {:ok, report_message}
assert SimplePolicy.filter(local_message) == {:ok, local_message}
end
test "has a matching host" do
clear_config([:mrf_simple, :report_removal], [{"remote.instance", "muh"}])
report_message = build_report_message()
local_message = build_local_message()
assert {:reject, _} = SimplePolicy.filter(report_message)
assert SimplePolicy.filter(local_message) == {:ok, local_message}
end
test "match with wildcard domain" do
clear_config([:mrf_simple, :report_removal], [{"*.remote.instance", "suya"}])
report_message = build_report_message()
local_message = build_local_message()
assert {:reject, _} = SimplePolicy.filter(report_message)
assert SimplePolicy.filter(local_message) == {:ok, local_message}
end
end
defp build_report_message do
%{
"actor" => "https://remote.instance/users/bob",
"type" => "Flag"
}
end
describe "when :federated_timeline_removal" do
test "is empty" do
clear_config([:mrf_simple, :federated_timeline_removal], [])
{_, ftl_message} = build_ftl_actor_and_message()
local_message = build_local_message()
assert SimplePolicy.filter(ftl_message) == {:ok, ftl_message}
assert SimplePolicy.filter(local_message) == {:ok, local_message}
end
test "has a matching host" do
{actor, ftl_message} = build_ftl_actor_and_message()
ftl_message_actor_host =
ftl_message
|> Map.fetch!("actor")
|> URI.parse()
|> Map.fetch!(:host)
clear_config([:mrf_simple, :federated_timeline_removal], [{ftl_message_actor_host, "uwu"}])
local_message = build_local_message()
assert {:ok, ftl_message} = SimplePolicy.filter(ftl_message)
assert actor.follower_address in ftl_message["to"]
refute actor.follower_address in ftl_message["cc"]
refute "https://www.w3.org/ns/activitystreams#Public" in ftl_message["to"]
assert "https://www.w3.org/ns/activitystreams#Public" in ftl_message["cc"]
assert SimplePolicy.filter(local_message) == {:ok, local_message}
end
test "match with wildcard domain" do
{actor, ftl_message} = build_ftl_actor_and_message()
ftl_message_actor_host =
ftl_message
|> Map.fetch!("actor")
|> URI.parse()
|> Map.fetch!(:host)
clear_config([:mrf_simple, :federated_timeline_removal], [
{"*." <> ftl_message_actor_host, "owo"}
])
local_message = build_local_message()
assert {:ok, ftl_message} = SimplePolicy.filter(ftl_message)
assert actor.follower_address in ftl_message["to"]
refute actor.follower_address in ftl_message["cc"]
refute "https://www.w3.org/ns/activitystreams#Public" in ftl_message["to"]
assert "https://www.w3.org/ns/activitystreams#Public" in ftl_message["cc"]
assert SimplePolicy.filter(local_message) == {:ok, local_message}
end
test "has a matching host but only as:Public in to" do
{_actor, ftl_message} = build_ftl_actor_and_message()
ftl_message_actor_host =
ftl_message
|> Map.fetch!("actor")
|> URI.parse()
|> Map.fetch!(:host)
ftl_message = Map.put(ftl_message, "cc", [])
clear_config([: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"]
assert "https://www.w3.org/ns/activitystreams#Public" in ftl_message["cc"]
end
end
defp build_ftl_actor_and_message do
actor = insert(:user)
{actor,
%{
"actor" => actor.ap_id,
"to" => ["https://www.w3.org/ns/activitystreams#Public", "http://foo.bar/baz"],
"cc" => [actor.follower_address, "http://foo.bar/qux"]
}}
end
describe "when :reject" do
test "is empty" do
clear_config([:mrf_simple, :reject], [])
remote_message = build_remote_message()
assert SimplePolicy.filter(remote_message) == {:ok, remote_message}
end
test "activity has a matching host" do
clear_config([:mrf_simple, :reject], [{"remote.instance", ""}])
remote_message = build_remote_message()
assert {:reject, _} = SimplePolicy.filter(remote_message)
end
test "activity matches with wildcard domain" do
clear_config([:mrf_simple, :reject], [{"*.remote.instance", ""}])
remote_message = build_remote_message()
assert {:reject, _} = SimplePolicy.filter(remote_message)
end
test "actor has a matching host" do
clear_config([:mrf_simple, :reject], [{"remote.instance", ""}])
remote_user = build_remote_user()
assert {:reject, _} = SimplePolicy.filter(remote_user)
end
test "reject Announce when object would be rejected" do
clear_config([:mrf_simple, :reject], [{"blocked.tld", ""}])
announce = %{
"type" => "Announce",
"actor" => "https://okay.tld/users/alice",
"object" => %{"type" => "Note", "actor" => "https://blocked.tld/users/bob"}
}
assert {:reject, _} = SimplePolicy.filter(announce)
end
test "reject by URI object" do
clear_config([:mrf_simple, :reject], [{"blocked.tld", ""}])
announce = %{
"type" => "Announce",
"actor" => "https://okay.tld/users/alice",
"object" => "https://blocked.tld/activities/1"
}
assert {:reject, _} = SimplePolicy.filter(announce)
end
end
describe "when :followers_only" do
test "is empty" do
clear_config([:mrf_simple, :followers_only], [])
{_, ftl_message} = build_ftl_actor_and_message()
local_message = build_local_message()
assert SimplePolicy.filter(ftl_message) == {:ok, ftl_message}
assert SimplePolicy.filter(local_message) == {:ok, local_message}
end
test "has a matching host" do
actor = insert(:user)
following_user = insert(:user)
non_following_user = insert(:user)
{:ok, _, _, _} = CommonAPI.follow(following_user, actor)
activity = %{
"actor" => actor.ap_id,
"to" => [
"https://www.w3.org/ns/activitystreams#Public",
following_user.ap_id,
non_following_user.ap_id
],
"cc" => [actor.follower_address, "http://foo.bar/qux"]
}
dm_activity = %{
"actor" => actor.ap_id,
"to" => [
following_user.ap_id,
non_following_user.ap_id
],
"cc" => []
}
actor_domain =
activity
|> Map.fetch!("actor")
|> URI.parse()
|> Map.fetch!(:host)
clear_config([:mrf_simple, :followers_only], [{actor_domain, ""}])
assert {:ok, new_activity} = SimplePolicy.filter(activity)
assert actor.follower_address in new_activity["cc"]
assert following_user.ap_id in new_activity["to"]
refute "https://www.w3.org/ns/activitystreams#Public" in new_activity["to"]
refute "https://www.w3.org/ns/activitystreams#Public" in new_activity["cc"]
refute non_following_user.ap_id in new_activity["to"]
refute non_following_user.ap_id in new_activity["cc"]
assert {:ok, new_dm_activity} = SimplePolicy.filter(dm_activity)
assert new_dm_activity["to"] == [following_user.ap_id]
assert new_dm_activity["cc"] == []
end
end
describe "when :accept" do
test "is empty" do
clear_config([:mrf_simple, :accept], [])
local_message = build_local_message()
remote_message = build_remote_message()
assert SimplePolicy.filter(local_message) == {:ok, local_message}
assert SimplePolicy.filter(remote_message) == {:ok, remote_message}
end
test "is not empty but activity doesn't have a matching host" do
clear_config([:mrf_simple, :accept], [{"non.matching.remote", ""}])
local_message = build_local_message()
remote_message = build_remote_message()
assert SimplePolicy.filter(local_message) == {:ok, local_message}
assert {:reject, _} = SimplePolicy.filter(remote_message)
end
test "activity has a matching host" do
clear_config([:mrf_simple, :accept], [{"remote.instance", ""}])
local_message = build_local_message()
remote_message = build_remote_message()
assert SimplePolicy.filter(local_message) == {:ok, local_message}
assert SimplePolicy.filter(remote_message) == {:ok, remote_message}
end
test "activity matches with wildcard domain" do
clear_config([:mrf_simple, :accept], [{"*.remote.instance", ""}])
local_message = build_local_message()
remote_message = build_remote_message()
assert SimplePolicy.filter(local_message) == {:ok, local_message}
assert SimplePolicy.filter(remote_message) == {:ok, remote_message}
end
test "actor has a matching host" do
clear_config([:mrf_simple, :accept], [{"remote.instance", ""}])
remote_user = build_remote_user()
assert SimplePolicy.filter(remote_user) == {:ok, remote_user}
end
end
describe "when :avatar_removal" do
test "is empty" do
clear_config([:mrf_simple, :avatar_removal], [])
remote_user = build_remote_user()
assert SimplePolicy.filter(remote_user) == {:ok, remote_user}
end
test "is not empty but it doesn't have a matching host" do
clear_config([:mrf_simple, :avatar_removal], [{"non.matching.remote", ""}])
remote_user = build_remote_user()
assert SimplePolicy.filter(remote_user) == {:ok, remote_user}
end
test "has a matching host" do
clear_config([:mrf_simple, :avatar_removal], [{"remote.instance", ""}])
remote_user = build_remote_user()
{:ok, filtered} = SimplePolicy.filter(remote_user)
refute filtered["icon"]
end
test "match with wildcard domain" do
clear_config([:mrf_simple, :avatar_removal], [{"*.remote.instance", ""}])
remote_user = build_remote_user()
{:ok, filtered} = SimplePolicy.filter(remote_user)
refute filtered["icon"]
end
end
describe "when :banner_removal" do
test "is empty" do
clear_config([:mrf_simple, :banner_removal], [])
remote_user = build_remote_user()
assert SimplePolicy.filter(remote_user) == {:ok, remote_user}
end
test "is not empty but it doesn't have a matching host" do
clear_config([:mrf_simple, :banner_removal], [{"non.matching.remote", ""}])
remote_user = build_remote_user()
assert SimplePolicy.filter(remote_user) == {:ok, remote_user}
end
test "has a matching host" do
clear_config([:mrf_simple, :banner_removal], [{"remote.instance", ""}])
remote_user = build_remote_user()
{:ok, filtered} = SimplePolicy.filter(remote_user)
refute filtered["image"]
end
test "match with wildcard domain" do
clear_config([:mrf_simple, :banner_removal], [{"*.remote.instance", ""}])
remote_user = build_remote_user()
{:ok, filtered} = SimplePolicy.filter(remote_user)
refute filtered["image"]
end
end
describe "when :reject_deletes is empty" do
setup do: clear_config([:mrf_simple, :reject_deletes], [])
test "it accepts deletions even from rejected servers" do
clear_config([:mrf_simple, :reject], [{"remote.instance", ""}])
deletion_message = build_remote_deletion_message()
assert SimplePolicy.filter(deletion_message) == {:ok, deletion_message}
end
test "it accepts deletions even from non-whitelisted servers" do
clear_config([:mrf_simple, :accept], [{"non.matching.remote", ""}])
deletion_message = build_remote_deletion_message()
assert SimplePolicy.filter(deletion_message) == {:ok, deletion_message}
end
end
describe "when :reject_deletes is not empty but it doesn't have a matching host" do
setup do: clear_config([:mrf_simple, :reject_deletes], [{"non.matching.remote", ""}])
test "it accepts deletions even from rejected servers" do
clear_config([:mrf_simple, :reject], [{"remote.instance", ""}])
deletion_message = build_remote_deletion_message()
assert SimplePolicy.filter(deletion_message) == {:ok, deletion_message}
end
test "it accepts deletions even from non-whitelisted servers" do
clear_config([:mrf_simple, :accept], [{"non.matching.remote", ""}])
deletion_message = build_remote_deletion_message()
assert SimplePolicy.filter(deletion_message) == {:ok, deletion_message}
end
end
describe "when :reject_deletes has a matching host" do
setup do: clear_config([:mrf_simple, :reject_deletes], [{"remote.instance", ""}])
test "it rejects the deletion" do
deletion_message = build_remote_deletion_message()
assert {:reject, _} = SimplePolicy.filter(deletion_message)
end
end
describe "when :reject_deletes match with wildcard domain" do
setup do: clear_config([:mrf_simple, :reject_deletes], [{"*.remote.instance", ""}])
test "it rejects the deletion" do
deletion_message = build_remote_deletion_message()
assert {:reject, _} = SimplePolicy.filter(deletion_message)
end
end
defp build_local_message do
%{
"actor" => "#{Pleroma.Web.Endpoint.url()}/users/alice",
"to" => [],
"cc" => []
}
end
defp build_remote_message do
%{"actor" => "https://remote.instance/users/bob"}
end
defp build_remote_user do
%{
"id" => "https://remote.instance/users/bob",
"icon" => %{
"url" => "http://example.com/image.jpg",
"type" => "Image"
},
"image" => %{
"url" => "http://example.com/image.jpg",
"type" => "Image"
},
"type" => "Person"
}
end
defp build_remote_deletion_message do
%{
"type" => "Delete",
"actor" => "https://remote.instance/users/bob"
}
end
end

File Metadata

Mime Type
text/x-diff
Expires
Sun, Aug 30, 12:24 PM (1 d, 23 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1737964
Default Alt Text
(30 KB)

Event Timeline