Add :reject_deletes option to SimplePolicy

This commit is contained in:
Alex Gleason 2020-04-13 13:48:32 -05:00
parent 9a3c74b244
commit b54c8813d6
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
6 changed files with 89 additions and 22 deletions

View File

@ -12,6 +12,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- NodeInfo: `pleroma_emoji_reactions` to the `features` list. - NodeInfo: `pleroma_emoji_reactions` to the `features` list.
- Configuration: `:restrict_unauthenticated` setting, restrict access for unauthenticated users to timelines (public and federate), user profiles and statuses. - Configuration: `:restrict_unauthenticated` setting, restrict access for unauthenticated users to timelines (public and federate), user profiles and statuses.
- New HTTP adapter [gun](https://github.com/ninenines/gun). Gun adapter requires minimum OTP version of 22.2 otherwise Pleroma wont start. For hackney OTP update is not required. - New HTTP adapter [gun](https://github.com/ninenines/gun). Gun adapter requires minimum OTP version of 22.2 otherwise Pleroma wont start. For hackney OTP update is not required.
- Added `:reject_deletes` group to SimplePolicy
<details> <details>
<summary>API Changes</summary> <summary>API Changes</summary>
- Mastodon API: Support for `include_types` in `/api/v1/notifications`. - Mastodon API: Support for `include_types` in `/api/v1/notifications`.
@ -20,6 +21,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Fixed ### Fixed
- Support pagination in conversations API - Support pagination in conversations API
- **Breaking**: SimplePolicy `:reject` and `:accept` allow deletions again
## [unreleased-patch] ## [unreleased-patch]

View File

@ -334,7 +334,8 @@
reject: [], reject: [],
accept: [], accept: [],
avatar_removal: [], avatar_removal: [],
banner_removal: [] banner_removal: [],
reject_deletes: []
config :pleroma, :mrf_keyword, config :pleroma, :mrf_keyword,
reject: [], reject: [],

View File

@ -1317,13 +1317,13 @@
%{ %{
key: :reject, key: :reject,
type: {:list, :string}, type: {:list, :string},
description: "List of instances to reject any activities from", description: "List of instances to reject activities from (except deletes)",
suggestions: ["example.com", "*.example.com"] suggestions: ["example.com", "*.example.com"]
}, },
%{ %{
key: :accept, key: :accept,
type: {:list, :string}, type: {:list, :string},
description: "List of instances to accept any activities from", description: "List of instances to only accept activities from (except deletes)",
suggestions: ["example.com", "*.example.com"] suggestions: ["example.com", "*.example.com"]
}, },
%{ %{
@ -1343,6 +1343,12 @@
type: {:list, :string}, type: {:list, :string},
description: "List of instances to strip banners from", description: "List of instances to strip banners from",
suggestions: ["example.com", "*.example.com"] suggestions: ["example.com", "*.example.com"]
},
%{
key: :reject_deletes,
type: {:list, :string},
description: "List of instances to reject deletions from",
suggestions: ["example.com", "*.example.com"]
} }
] ]
}, },

View File

@ -43,9 +43,10 @@ Once `SimplePolicy` is enabled, you can configure various groups in the `:mrf_si
* `media_removal`: Servers in this group will have media stripped from incoming messages. * `media_removal`: Servers in this group will have media stripped from incoming messages.
* `media_nsfw`: Servers in this group will have the #nsfw tag and sensitive setting injected into incoming messages which contain media. * `media_nsfw`: Servers in this group will have the #nsfw tag and sensitive setting injected into incoming messages which contain media.
* `reject`: Servers in this group will have their messages rejected. * `reject`: Servers in this group will have their messages (except deletions) rejected.
* `federated_timeline_removal`: Servers in this group will have their messages unlisted from the public timelines by flipping the `to` and `cc` fields. * `federated_timeline_removal`: Servers in this group will have their messages unlisted from the public timelines by flipping the `to` and `cc` fields.
* `report_removal`: Servers in this group will have their reports (flags) rejected. * `report_removal`: Servers in this group will have their reports (flags) rejected.
* `reject_deletes`: Deletion requests will be rejected from these servers.
Servers should be configured as lists. Servers should be configured as lists.

View File

@ -149,7 +149,19 @@ defp check_banner_removal(%{host: actor_host} = _actor_info, %{"image" => _image
defp check_banner_removal(_actor_info, object), do: {:ok, object} defp check_banner_removal(_actor_info, object), do: {:ok, object}
@impl true @impl true
def filter(%{"type" => "Delete"} = object), do: {:ok, object} def filter(%{"type" => "Delete", "actor" => actor} = object) do
%{host: actor_host} = URI.parse(actor)
reject_deletes =
Pleroma.Config.get([:mrf_simple, :reject_deletes])
|> MRF.subdomains_regex()
if MRF.subdomain_match?(reject_deletes, actor_host) do
{:reject, nil}
else
{:ok, object}
end
end
@impl true @impl true
def filter(%{"actor" => actor} = object) do def filter(%{"actor" => actor} = object) do

View File

@ -17,7 +17,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
reject: [], reject: [],
accept: [], accept: [],
avatar_removal: [], avatar_removal: [],
banner_removal: [] banner_removal: [],
reject_deletes: []
) )
describe "when :media_removal" do describe "when :media_removal" do
@ -258,14 +259,6 @@ test "actor has a matching host" do
assert SimplePolicy.filter(remote_user) == {:reject, nil} assert SimplePolicy.filter(remote_user) == {:reject, nil}
end end
test "always accept deletions" do
Config.put([:mrf_simple, :reject], ["remote.instance"])
deletion_message = build_remote_deletion_message()
assert SimplePolicy.filter(deletion_message) == {:ok, deletion_message}
end
end end
describe "when :accept" do describe "when :accept" do
@ -316,14 +309,6 @@ test "actor has a matching host" do
assert SimplePolicy.filter(remote_user) == {:ok, remote_user} assert SimplePolicy.filter(remote_user) == {:ok, remote_user}
end end
test "always accept deletions" do
Config.put([:mrf_simple, :accept], ["non.matching.remote"])
deletion_message = build_remote_deletion_message()
assert SimplePolicy.filter(deletion_message) == {:ok, deletion_message}
end
end end
describe "when :avatar_removal" do describe "when :avatar_removal" do
@ -398,6 +383,66 @@ test "match with wildcard domain" do
end end
end end
describe "when :reject_deletes is empty" 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"])
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
Config.put([: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: 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"])
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
Config.put([: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: Config.put([:mrf_simple, :reject_deletes], ["remote.instance"])
test "it rejects the deletion" do
deletion_message = build_remote_deletion_message()
assert SimplePolicy.filter(deletion_message) == {:reject, nil}
end
end
describe "when :reject_deletes match with wildcard domain" do
setup do: Config.put([:mrf_simple, :reject_deletes], ["*.remote.instance"])
test "it rejects the deletion" do
deletion_message = build_remote_deletion_message()
assert SimplePolicy.filter(deletion_message) == {:reject, nil}
end
end
defp build_local_message do defp build_local_message do
%{ %{
"actor" => "#{Pleroma.Web.base_url()}/users/alice", "actor" => "#{Pleroma.Web.base_url()}/users/alice",