Add ability to obfuscate domains in MRF transparency

This commit is contained in:
FloatingGhost 2022-08-27 11:57:57 +01:00
parent f11a6eb8dd
commit 85137f591f
6 changed files with 80 additions and 3 deletions

View file

@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- support for fedibird-fe, and non-breaking API parity for it to function - support for fedibird-fe, and non-breaking API parity for it to function
- support for setting instance languages in metadata - support for setting instance languages in metadata
- support for reusing oauth tokens, and not requiring new authorizations - support for reusing oauth tokens, and not requiring new authorizations
- the ability to obfuscate domains in your MRF descriptions
### Changed ### Changed
- MFM parsing is now done on the backend by a modified version of ilja's parser -> https://akkoma.dev/AkkomaGang/mfm-parser - MFM parsing is now done on the backend by a modified version of ilja's parser -> https://akkoma.dev/AkkomaGang/mfm-parser

View file

@ -794,7 +794,8 @@
config :pleroma, :mrf, config :pleroma, :mrf,
policies: [Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy, Pleroma.Web.ActivityPub.MRF.TagPolicy], policies: [Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy, Pleroma.Web.ActivityPub.MRF.TagPolicy],
transparency: true, transparency: true,
transparency_exclusions: [] transparency_exclusions: [],
transparency_obfuscate_domains: []
config :ex_aws, http_client: Pleroma.HTTP.ExAws config :ex_aws, http_client: Pleroma.HTTP.ExAws

View file

@ -120,6 +120,7 @@ To add configuration to your config file, you can copy it from the base config.
* `Pleroma.Web.ActivityPub.MRF.KeywordPolicy`: Rejects or removes from the federated timeline or replaces keywords. (See [`:mrf_keyword`](#mrf_keyword)). * `Pleroma.Web.ActivityPub.MRF.KeywordPolicy`: Rejects or removes from the federated timeline or replaces keywords. (See [`:mrf_keyword`](#mrf_keyword)).
* `transparency`: Make the content of your Message Rewrite Facility settings public (via nodeinfo). * `transparency`: Make the content of your Message Rewrite Facility settings public (via nodeinfo).
* `transparency_exclusions`: Exclude specific instance names from MRF transparency. The use of the exclusions feature will be disclosed in nodeinfo as a boolean value. * `transparency_exclusions`: Exclude specific instance names from MRF transparency. The use of the exclusions feature will be disclosed in nodeinfo as a boolean value.
* `transparency_obfuscate_domains`: Show domains with `*` in the middle, to censor them if needed. For example, `ridingho.me` will show as `rid*****.me`
## Federation ## Federation
### MRF policies ### MRF policies

View file

@ -41,6 +41,16 @@ defmodule Pleroma.Web.ActivityPub.MRF do
suggestions: [ suggestions: [
"exclusion.com" "exclusion.com"
] ]
},
%{
key: :transparency_obfuscate_domains,
label: "MRF domain obfuscation",
type: {:list, :string},
description:
"Obfuscate domains in MRF transparency. This is useful if the domain you're blocking contains words you don't want displayed, but still want to disclose the MRF settings.",
suggestions: [
"badword.com"
]
} }
] ]
} }

View file

@ -256,10 +256,35 @@ def filter(object) when is_binary(object) do
def filter(object), do: {:ok, object} def filter(object), do: {:ok, object}
defp obfuscate(string) when is_binary(string) do
string
|> to_charlist()
|> Enum.with_index()
|> Enum.map(fn
{?., _index} ->
?.
{char, index} ->
if 3 <= index && index < String.length(string) - 3, do: ?*, else: char
end)
|> to_string()
end
defp maybe_obfuscate(host, obfuscations) do
if MRF.subdomain_match?(obfuscations, host) do
obfuscate(host)
else
host
end
end
@impl true @impl true
def describe do def describe do
exclusions = Config.get([:mrf, :transparency_exclusions]) |> MRF.instance_list_from_tuples() exclusions = Config.get([:mrf, :transparency_exclusions]) |> MRF.instance_list_from_tuples()
obfuscations =
Config.get([:mrf, :transparency_obfuscate_domains], []) |> MRF.subdomains_regex()
mrf_simple_excluded = mrf_simple_excluded =
Config.get(:mrf_simple) Config.get(:mrf_simple)
|> Enum.map(fn {rule, instances} -> |> Enum.map(fn {rule, instances} ->
@ -269,7 +294,7 @@ def describe do
mrf_simple = mrf_simple =
mrf_simple_excluded mrf_simple_excluded
|> Enum.map(fn {rule, instances} -> |> Enum.map(fn {rule, instances} ->
{rule, Enum.map(instances, fn {host, _} -> host end)} {rule, Enum.map(instances, fn {host, _} -> maybe_obfuscate(host, obfuscations) end)}
end) end)
|> Map.new() |> Map.new()
@ -286,7 +311,9 @@ def describe do
|> Enum.map(fn {rule, instances} -> |> Enum.map(fn {rule, instances} ->
instances = instances =
instances instances
|> Enum.map(fn {host, reason} -> {host, %{"reason" => reason}} end) |> Enum.map(fn {host, reason} ->
{maybe_obfuscate(host, obfuscations), %{"reason" => reason}}
end)
|> Map.new() |> Map.new()
{rule, instances} {rule, instances}

View file

@ -216,6 +216,43 @@ test "has a matching host but only as:Public in to" do
end end
end end
describe "describe/1" do
test "returns a description of the policy" do
clear_config([:mrf_simple, :reject], [
{"remote.instance", "did not give my catboy a burg"}
])
assert {:ok, %{mrf_simple: %{reject: ["remote.instance"]}}} = SimplePolicy.describe()
end
test "excludes domains listed in :transparency_exclusions" do
clear_config([:mrf, :transparency_exclusions], [{"remote.instance", ":("}])
clear_config([:mrf_simple, :reject], [
{"remote.instance", "did not give my catboy a burg"}
])
{:ok, description} = SimplePolicy.describe()
assert %{mrf_simple: %{reject: []}} = description
assert description[:mrf_simple_info][:reject] == nil
end
test "obfuscates domains listed in :transparency_obfuscate_domains" do
clear_config([:mrf, :transparency_obfuscate_domains], ["remote.instance", "a.b"])
clear_config([:mrf_simple, :reject], [
{"remote.instance", "did not give my catboy a burg"},
{"a.b", "spam-poked me on facebook in 2006"}
])
assert {:ok,
%{
mrf_simple: %{reject: ["rem***.*****nce", "a.b"]},
mrf_simple_info: %{reject: %{"rem***.*****nce" => %{}}}
}} = SimplePolicy.describe()
end
end
defp build_ftl_actor_and_message do defp build_ftl_actor_and_message do
actor = insert(:user) actor = insert(:user)