forked from AkkomaGang/akkoma
Merge branch 'feature/2222-config-descriptions-for-custom-modules' into 'develop'
Config descriptions for custom MRF policies Closes #2222 See merge request pleroma/pleroma!3128
This commit is contained in:
commit
3cd7ea693f
16 changed files with 454 additions and 339 deletions
|
@ -1,5 +1,4 @@
|
||||||
use Mix.Config
|
use Mix.Config
|
||||||
alias Pleroma.Docs.Generator
|
|
||||||
|
|
||||||
websocket_config = [
|
websocket_config = [
|
||||||
path: "/websocket",
|
path: "/websocket",
|
||||||
|
@ -1555,298 +1554,6 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
%{
|
|
||||||
group: :pleroma,
|
|
||||||
key: :mrf,
|
|
||||||
tab: :mrf,
|
|
||||||
label: "MRF",
|
|
||||||
type: :group,
|
|
||||||
description: "General MRF settings",
|
|
||||||
children: [
|
|
||||||
%{
|
|
||||||
key: :policies,
|
|
||||||
type: [:module, {:list, :module}],
|
|
||||||
description:
|
|
||||||
"A list of MRF policies enabled. Module names are shortened (removed leading `Pleroma.Web.ActivityPub.MRF.` part), but on adding custom module you need to use full name.",
|
|
||||||
suggestions: {:list_behaviour_implementations, Pleroma.Web.ActivityPub.MRF}
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :transparency,
|
|
||||||
label: "MRF transparency",
|
|
||||||
type: :boolean,
|
|
||||||
description:
|
|
||||||
"Make the content of your Message Rewrite Facility settings public (via nodeinfo)"
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :transparency_exclusions,
|
|
||||||
label: "MRF transparency exclusions",
|
|
||||||
type: {:list, :string},
|
|
||||||
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"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
group: :pleroma,
|
|
||||||
key: :mrf_simple,
|
|
||||||
tab: :mrf,
|
|
||||||
related_policy: "Pleroma.Web.ActivityPub.MRF.SimplePolicy",
|
|
||||||
label: "MRF Simple",
|
|
||||||
type: :group,
|
|
||||||
description: "Simple ingress policies",
|
|
||||||
children: [
|
|
||||||
%{
|
|
||||||
key: :media_removal,
|
|
||||||
type: {:list, :string},
|
|
||||||
description: "List of instances to strip media attachments from",
|
|
||||||
suggestions: ["example.com", "*.example.com"]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
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"]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :federated_timeline_removal,
|
|
||||||
type: {:list, :string},
|
|
||||||
description:
|
|
||||||
"List of instances to remove from the Federated (aka The Whole Known Network) Timeline",
|
|
||||||
suggestions: ["example.com", "*.example.com"]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :reject,
|
|
||||||
type: {:list, :string},
|
|
||||||
description: "List of instances to reject activities from (except deletes)",
|
|
||||||
suggestions: ["example.com", "*.example.com"]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :accept,
|
|
||||||
type: {:list, :string},
|
|
||||||
description: "List of instances to only accept activities from (except deletes)",
|
|
||||||
suggestions: ["example.com", "*.example.com"]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :followers_only,
|
|
||||||
type: {:list, :string},
|
|
||||||
description: "Force posts from the given instances to be visible by followers only",
|
|
||||||
suggestions: ["example.com", "*.example.com"]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :report_removal,
|
|
||||||
type: {:list, :string},
|
|
||||||
description: "List of instances to reject reports from",
|
|
||||||
suggestions: ["example.com", "*.example.com"]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :avatar_removal,
|
|
||||||
type: {:list, :string},
|
|
||||||
description: "List of instances to strip avatars from",
|
|
||||||
suggestions: ["example.com", "*.example.com"]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :banner_removal,
|
|
||||||
type: {:list, :string},
|
|
||||||
description: "List of instances to strip banners from",
|
|
||||||
suggestions: ["example.com", "*.example.com"]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :reject_deletes,
|
|
||||||
type: {:list, :string},
|
|
||||||
description: "List of instances to reject deletions from",
|
|
||||||
suggestions: ["example.com", "*.example.com"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
group: :pleroma,
|
|
||||||
key: :mrf_activity_expiration,
|
|
||||||
tab: :mrf,
|
|
||||||
related_policy: "Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy",
|
|
||||||
label: "MRF Activity Expiration Policy",
|
|
||||||
type: :group,
|
|
||||||
description: "Adds automatic expiration to all local activities",
|
|
||||||
children: [
|
|
||||||
%{
|
|
||||||
key: :days,
|
|
||||||
type: :integer,
|
|
||||||
description: "Default global expiration time for all local activities (in days)",
|
|
||||||
suggestions: [90, 365]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
group: :pleroma,
|
|
||||||
key: :mrf_subchain,
|
|
||||||
tab: :mrf,
|
|
||||||
related_policy: "Pleroma.Web.ActivityPub.MRF.SubchainPolicy",
|
|
||||||
label: "MRF Subchain",
|
|
||||||
type: :group,
|
|
||||||
description:
|
|
||||||
"This policy processes messages through an alternate pipeline when a given message matches certain criteria." <>
|
|
||||||
" All criteria are configured as a map of regular expressions to lists of policy modules.",
|
|
||||||
children: [
|
|
||||||
%{
|
|
||||||
key: :match_actor,
|
|
||||||
type: {:map, {:list, :string}},
|
|
||||||
description: "Matches a series of regular expressions against the actor field",
|
|
||||||
suggestions: [
|
|
||||||
%{
|
|
||||||
~r/https:\/\/example.com/s => [Pleroma.Web.ActivityPub.MRF.DropPolicy]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
group: :pleroma,
|
|
||||||
key: :mrf_rejectnonpublic,
|
|
||||||
tab: :mrf,
|
|
||||||
related_policy: "Pleroma.Web.ActivityPub.MRF.RejectNonPublic",
|
|
||||||
description: "RejectNonPublic drops posts with non-public visibility settings.",
|
|
||||||
label: "MRF Reject Non Public",
|
|
||||||
type: :group,
|
|
||||||
children: [
|
|
||||||
%{
|
|
||||||
key: :allow_followersonly,
|
|
||||||
label: "Allow followers-only",
|
|
||||||
type: :boolean,
|
|
||||||
description: "Whether to allow followers-only posts"
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :allow_direct,
|
|
||||||
type: :boolean,
|
|
||||||
description: "Whether to allow direct messages"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
group: :pleroma,
|
|
||||||
key: :mrf_hellthread,
|
|
||||||
tab: :mrf,
|
|
||||||
related_policy: "Pleroma.Web.ActivityPub.MRF.HellthreadPolicy",
|
|
||||||
label: "MRF Hellthread",
|
|
||||||
type: :group,
|
|
||||||
description: "Block messages with excessive user mentions",
|
|
||||||
children: [
|
|
||||||
%{
|
|
||||||
key: :delist_threshold,
|
|
||||||
type: :integer,
|
|
||||||
description:
|
|
||||||
"Number of mentioned users after which the message gets removed from timelines and" <>
|
|
||||||
"disables notifications. Set to 0 to disable.",
|
|
||||||
suggestions: [10]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :reject_threshold,
|
|
||||||
type: :integer,
|
|
||||||
description:
|
|
||||||
"Number of mentioned users after which the messaged gets rejected. Set to 0 to disable.",
|
|
||||||
suggestions: [20]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
group: :pleroma,
|
|
||||||
key: :mrf_keyword,
|
|
||||||
tab: :mrf,
|
|
||||||
related_policy: "Pleroma.Web.ActivityPub.MRF.KeywordPolicy",
|
|
||||||
label: "MRF Keyword",
|
|
||||||
type: :group,
|
|
||||||
description:
|
|
||||||
"Reject or Word-Replace messages matching a keyword or [Regex](https://hexdocs.pm/elixir/Regex.html).",
|
|
||||||
children: [
|
|
||||||
%{
|
|
||||||
key: :reject,
|
|
||||||
type: {:list, :string},
|
|
||||||
description: """
|
|
||||||
A list of patterns which result in message being rejected.
|
|
||||||
|
|
||||||
Each pattern can be a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.
|
|
||||||
""",
|
|
||||||
suggestions: ["foo", ~r/foo/iu]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :federated_timeline_removal,
|
|
||||||
type: {:list, :string},
|
|
||||||
description: """
|
|
||||||
A list of patterns which result in message being removed from federated timelines (a.k.a unlisted).
|
|
||||||
|
|
||||||
Each pattern can be a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.
|
|
||||||
""",
|
|
||||||
suggestions: ["foo", ~r/foo/iu]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :replace,
|
|
||||||
type: {:list, :tuple},
|
|
||||||
description: """
|
|
||||||
**Pattern**: a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.
|
|
||||||
|
|
||||||
**Replacement**: a string. Leaving the field empty is permitted.
|
|
||||||
"""
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
group: :pleroma,
|
|
||||||
key: :mrf_mention,
|
|
||||||
tab: :mrf,
|
|
||||||
related_policy: "Pleroma.Web.ActivityPub.MRF.MentionPolicy",
|
|
||||||
label: "MRF Mention",
|
|
||||||
type: :group,
|
|
||||||
description: "Block messages which mention a specific user",
|
|
||||||
children: [
|
|
||||||
%{
|
|
||||||
key: :actors,
|
|
||||||
type: {:list, :string},
|
|
||||||
description: "A list of actors for which any post mentioning them will be dropped",
|
|
||||||
suggestions: ["actor1", "actor2"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
group: :pleroma,
|
|
||||||
key: :mrf_vocabulary,
|
|
||||||
tab: :mrf,
|
|
||||||
related_policy: "Pleroma.Web.ActivityPub.MRF.VocabularyPolicy",
|
|
||||||
label: "MRF Vocabulary",
|
|
||||||
type: :group,
|
|
||||||
description: "Filter messages which belong to certain activity vocabularies",
|
|
||||||
children: [
|
|
||||||
%{
|
|
||||||
key: :accept,
|
|
||||||
type: {:list, :string},
|
|
||||||
description:
|
|
||||||
"A list of ActivityStreams terms to accept. If empty, all supported messages are accepted.",
|
|
||||||
suggestions: ["Create", "Follow", "Mention", "Announce", "Like"]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :reject,
|
|
||||||
type: {:list, :string},
|
|
||||||
description:
|
|
||||||
"A list of ActivityStreams terms to reject. If empty, no messages are rejected.",
|
|
||||||
suggestions: ["Create", "Follow", "Mention", "Announce", "Like"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
# %{
|
|
||||||
# group: :pleroma,
|
|
||||||
# key: :mrf_user_allowlist,
|
|
||||||
# tab: :mrf,
|
|
||||||
# related_policy: "Pleroma.Web.ActivityPub.MRF.UserAllowListPolicy",
|
|
||||||
# type: :map,
|
|
||||||
# description:
|
|
||||||
# "The keys in this section are the domain names that the policy should apply to." <>
|
|
||||||
# " Each key should be assigned a list of users that should be allowed through by their ActivityPub ID",
|
|
||||||
# suggestions: [
|
|
||||||
# %{"example.org" => ["https://example.org/users/admin"]}
|
|
||||||
# ]
|
|
||||||
# ]
|
|
||||||
# },
|
|
||||||
%{
|
%{
|
||||||
group: :pleroma,
|
group: :pleroma,
|
||||||
key: :media_proxy,
|
key: :media_proxy,
|
||||||
|
@ -3159,22 +2866,6 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
%{
|
|
||||||
group: :pleroma,
|
|
||||||
key: :mrf_normalize_markup,
|
|
||||||
tab: :mrf,
|
|
||||||
related_policy: "Pleroma.Web.ActivityPub.MRF.NormalizeMarkup",
|
|
||||||
label: "MRF Normalize Markup",
|
|
||||||
description: "MRF NormalizeMarkup settings. Scrub configured hypertext markup.",
|
|
||||||
type: :group,
|
|
||||||
children: [
|
|
||||||
%{
|
|
||||||
key: :scrub_policy,
|
|
||||||
type: :module,
|
|
||||||
suggestions: [Pleroma.HTML.Scrubber.Default]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
%{
|
%{
|
||||||
group: :pleroma,
|
group: :pleroma,
|
||||||
key: Pleroma.User,
|
key: Pleroma.User,
|
||||||
|
@ -3364,33 +3055,6 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
%{
|
|
||||||
group: :pleroma,
|
|
||||||
key: :mrf_object_age,
|
|
||||||
tab: :mrf,
|
|
||||||
related_policy: "Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy",
|
|
||||||
label: "MRF Object Age",
|
|
||||||
type: :group,
|
|
||||||
description:
|
|
||||||
"Rejects or delists posts based on their timestamp deviance from your server's clock.",
|
|
||||||
children: [
|
|
||||||
%{
|
|
||||||
key: :threshold,
|
|
||||||
type: :integer,
|
|
||||||
description: "Required age (in seconds) of a post before actions are taken.",
|
|
||||||
suggestions: [172_800]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :actions,
|
|
||||||
type: {:list, :atom},
|
|
||||||
description:
|
|
||||||
"A list of actions to apply to the post. `:delist` removes the post from public timelines; " <>
|
|
||||||
"`:strip_followers` removes followers from the ActivityPub recipient list ensuring they won't be delivered to home timelines; " <>
|
|
||||||
"`:reject` rejects the message entirely",
|
|
||||||
suggestions: [:delist, :strip_followers, :reject]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
%{
|
%{
|
||||||
group: :pleroma,
|
group: :pleroma,
|
||||||
key: :modules,
|
key: :modules,
|
||||||
|
|
|
@ -11,7 +11,11 @@ defmodule Pleroma.Docs.JSON do
|
||||||
|
|
||||||
@spec compile :: :ok
|
@spec compile :: :ok
|
||||||
def compile do
|
def compile do
|
||||||
:persistent_term.put(@term, Pleroma.Docs.Generator.convert_to_strings(@raw_descriptions))
|
descriptions =
|
||||||
|
Pleroma.Web.ActivityPub.MRF.config_descriptions()
|
||||||
|
|> Enum.reduce(@raw_descriptions, fn description, acc -> [description | acc] end)
|
||||||
|
|
||||||
|
:persistent_term.put(@term, Pleroma.Docs.Generator.convert_to_strings(descriptions))
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec compiled_descriptions :: Map.t()
|
@spec compiled_descriptions :: Map.t()
|
||||||
|
|
|
@ -3,7 +3,62 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.ActivityPub.MRF do
|
defmodule Pleroma.Web.ActivityPub.MRF do
|
||||||
|
require Logger
|
||||||
|
|
||||||
|
@mrf_config_descriptions [
|
||||||
|
%{
|
||||||
|
group: :pleroma,
|
||||||
|
key: :mrf,
|
||||||
|
tab: :mrf,
|
||||||
|
label: "MRF",
|
||||||
|
type: :group,
|
||||||
|
description: "General MRF settings",
|
||||||
|
children: [
|
||||||
|
%{
|
||||||
|
key: :policies,
|
||||||
|
type: [:module, {:list, :module}],
|
||||||
|
description:
|
||||||
|
"A list of MRF policies enabled. Module names are shortened (removed leading `Pleroma.Web.ActivityPub.MRF.` part), but on adding custom module you need to use full name.",
|
||||||
|
suggestions: {:list_behaviour_implementations, Pleroma.Web.ActivityPub.MRF}
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :transparency,
|
||||||
|
label: "MRF transparency",
|
||||||
|
type: :boolean,
|
||||||
|
description:
|
||||||
|
"Make the content of your Message Rewrite Facility settings public (via nodeinfo)"
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :transparency_exclusions,
|
||||||
|
label: "MRF transparency exclusions",
|
||||||
|
type: {:list, :string},
|
||||||
|
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"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
@default_description %{
|
||||||
|
label: "",
|
||||||
|
description: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
@required_description_keys [:key, :related_policy]
|
||||||
|
|
||||||
@callback filter(Map.t()) :: {:ok | :reject, Map.t()}
|
@callback filter(Map.t()) :: {:ok | :reject, Map.t()}
|
||||||
|
@callback describe() :: {:ok | :error, Map.t()}
|
||||||
|
@callback config_description() :: %{
|
||||||
|
optional(:children) => [map()],
|
||||||
|
key: atom(),
|
||||||
|
related_policy: String.t(),
|
||||||
|
label: String.t(),
|
||||||
|
description: String.t()
|
||||||
|
}
|
||||||
|
@optional_callbacks config_description: 0
|
||||||
|
|
||||||
def filter(policies, %{} = message) do
|
def filter(policies, %{} = message) do
|
||||||
policies
|
policies
|
||||||
|
@ -51,8 +106,6 @@ def subdomain_match?(domains, host) do
|
||||||
Enum.any?(domains, fn domain -> Regex.match?(domain, host) end)
|
Enum.any?(domains, fn domain -> Regex.match?(domain, host) end)
|
||||||
end
|
end
|
||||||
|
|
||||||
@callback describe() :: {:ok | :error, Map.t()}
|
|
||||||
|
|
||||||
def describe(policies) do
|
def describe(policies) do
|
||||||
{:ok, policy_configs} =
|
{:ok, policy_configs} =
|
||||||
policies
|
policies
|
||||||
|
@ -82,4 +135,41 @@ def describe(policies) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def describe, do: get_policies() |> describe()
|
def describe, do: get_policies() |> describe()
|
||||||
|
|
||||||
|
def config_descriptions do
|
||||||
|
Pleroma.Web.ActivityPub.MRF
|
||||||
|
|> Pleroma.Docs.Generator.list_behaviour_implementations()
|
||||||
|
|> config_descriptions()
|
||||||
|
end
|
||||||
|
|
||||||
|
def config_descriptions(policies) do
|
||||||
|
Enum.reduce(policies, @mrf_config_descriptions, fn policy, acc ->
|
||||||
|
if function_exported?(policy, :config_description, 0) do
|
||||||
|
description =
|
||||||
|
@default_description
|
||||||
|
|> Map.merge(policy.config_description)
|
||||||
|
|> Map.put(:group, :pleroma)
|
||||||
|
|> Map.put(:tab, :mrf)
|
||||||
|
|> Map.put(:type, :group)
|
||||||
|
|
||||||
|
if Enum.all?(@required_description_keys, &Map.has_key?(description, &1)) do
|
||||||
|
[description | acc]
|
||||||
|
else
|
||||||
|
Logger.warn(
|
||||||
|
"#{policy} config description doesn't have one or all required keys #{
|
||||||
|
inspect(@required_description_keys)
|
||||||
|
}"
|
||||||
|
)
|
||||||
|
|
||||||
|
acc
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Logger.info(
|
||||||
|
"#{policy} is excluded from config descriptions, because does not implement `config_description/0` method."
|
||||||
|
)
|
||||||
|
|
||||||
|
acc
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -40,4 +40,22 @@ defp maybe_add_expiration(activity) do
|
||||||
_ -> Map.put(activity, "expires_at", expires_at)
|
_ -> Map.put(activity, "expires_at", expires_at)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def config_description do
|
||||||
|
%{
|
||||||
|
key: :mrf_activity_expiration,
|
||||||
|
related_policy: "Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy",
|
||||||
|
label: "MRF Activity Expiration Policy",
|
||||||
|
description: "Adds automatic expiration to all local activities",
|
||||||
|
children: [
|
||||||
|
%{
|
||||||
|
key: :days,
|
||||||
|
type: :integer,
|
||||||
|
description: "Default global expiration time for all local activities (in days)",
|
||||||
|
suggestions: [90, 365]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -97,4 +97,31 @@ def filter(message), do: {:ok, message}
|
||||||
@impl true
|
@impl true
|
||||||
def describe,
|
def describe,
|
||||||
do: {:ok, %{mrf_hellthread: Pleroma.Config.get(:mrf_hellthread) |> Enum.into(%{})}}
|
do: {:ok, %{mrf_hellthread: Pleroma.Config.get(:mrf_hellthread) |> Enum.into(%{})}}
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def config_description do
|
||||||
|
%{
|
||||||
|
key: :mrf_hellthread,
|
||||||
|
related_policy: "Pleroma.Web.ActivityPub.MRF.HellthreadPolicy",
|
||||||
|
label: "MRF Hellthread",
|
||||||
|
description: "Block messages with excessive user mentions",
|
||||||
|
children: [
|
||||||
|
%{
|
||||||
|
key: :delist_threshold,
|
||||||
|
type: :integer,
|
||||||
|
description:
|
||||||
|
"Number of mentioned users after which the message gets removed from timelines and" <>
|
||||||
|
"disables notifications. Set to 0 to disable.",
|
||||||
|
suggestions: [10]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :reject_threshold,
|
||||||
|
type: :integer,
|
||||||
|
description:
|
||||||
|
"Number of mentioned users after which the messaged gets rejected. Set to 0 to disable.",
|
||||||
|
suggestions: [20]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -126,4 +126,46 @@ def describe do
|
||||||
|
|
||||||
{:ok, %{mrf_keyword: mrf_keyword}}
|
{:ok, %{mrf_keyword: mrf_keyword}}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def config_description do
|
||||||
|
%{
|
||||||
|
key: :mrf_keyword,
|
||||||
|
related_policy: "Pleroma.Web.ActivityPub.MRF.KeywordPolicy",
|
||||||
|
label: "MRF Keyword",
|
||||||
|
description:
|
||||||
|
"Reject or Word-Replace messages matching a keyword or [Regex](https://hexdocs.pm/elixir/Regex.html).",
|
||||||
|
children: [
|
||||||
|
%{
|
||||||
|
key: :reject,
|
||||||
|
type: {:list, :string},
|
||||||
|
description: """
|
||||||
|
A list of patterns which result in message being rejected.
|
||||||
|
|
||||||
|
Each pattern can be a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.
|
||||||
|
""",
|
||||||
|
suggestions: ["foo", ~r/foo/iu]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :federated_timeline_removal,
|
||||||
|
type: {:list, :string},
|
||||||
|
description: """
|
||||||
|
A list of patterns which result in message being removed from federated timelines (a.k.a unlisted).
|
||||||
|
|
||||||
|
Each pattern can be a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.
|
||||||
|
""",
|
||||||
|
suggestions: ["foo", ~r/foo/iu]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :replace,
|
||||||
|
type: {:list, :tuple},
|
||||||
|
description: """
|
||||||
|
**Pattern**: a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.
|
||||||
|
|
||||||
|
**Replacement**: a string. Leaving the field empty is permitted.
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -25,4 +25,22 @@ def filter(message), do: {:ok, message}
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def describe, do: {:ok, %{}}
|
def describe, do: {:ok, %{}}
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def config_description do
|
||||||
|
%{
|
||||||
|
key: :mrf_mention,
|
||||||
|
related_policy: "Pleroma.Web.ActivityPub.MRF.MentionPolicy",
|
||||||
|
label: "MRF Mention",
|
||||||
|
description: "Block messages which mention a specific user",
|
||||||
|
children: [
|
||||||
|
%{
|
||||||
|
key: :actors,
|
||||||
|
type: {:list, :string},
|
||||||
|
description: "A list of actors for which any post mentioning them will be dropped",
|
||||||
|
suggestions: ["actor1", "actor2"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,6 +8,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkup do
|
||||||
|
|
||||||
@behaviour Pleroma.Web.ActivityPub.MRF
|
@behaviour Pleroma.Web.ActivityPub.MRF
|
||||||
|
|
||||||
|
@impl true
|
||||||
def filter(%{"type" => "Create", "object" => child_object} = object) do
|
def filter(%{"type" => "Create", "object" => child_object} = object) do
|
||||||
scrub_policy = Pleroma.Config.get([:mrf_normalize_markup, :scrub_policy])
|
scrub_policy = Pleroma.Config.get([:mrf_normalize_markup, :scrub_policy])
|
||||||
|
|
||||||
|
@ -22,5 +23,23 @@ def filter(%{"type" => "Create", "object" => child_object} = object) do
|
||||||
|
|
||||||
def filter(object), do: {:ok, object}
|
def filter(object), do: {:ok, object}
|
||||||
|
|
||||||
|
@impl true
|
||||||
def describe, do: {:ok, %{}}
|
def describe, do: {:ok, %{}}
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def config_description do
|
||||||
|
%{
|
||||||
|
key: :mrf_normalize_markup,
|
||||||
|
related_policy: "Pleroma.Web.ActivityPub.MRF.NormalizeMarkup",
|
||||||
|
label: "MRF Normalize Markup",
|
||||||
|
description: "MRF NormalizeMarkup settings. Scrub configured hypertext markup.",
|
||||||
|
children: [
|
||||||
|
%{
|
||||||
|
key: :scrub_policy,
|
||||||
|
type: :module,
|
||||||
|
suggestions: [Pleroma.HTML.Scrubber.Default]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -106,4 +106,32 @@ def describe do
|
||||||
|
|
||||||
{:ok, %{mrf_object_age: mrf_object_age}}
|
{:ok, %{mrf_object_age: mrf_object_age}}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def config_description do
|
||||||
|
%{
|
||||||
|
key: :mrf_object_age,
|
||||||
|
related_policy: "Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy",
|
||||||
|
label: "MRF Object Age",
|
||||||
|
description:
|
||||||
|
"Rejects or delists posts based on their timestamp deviance from your server's clock.",
|
||||||
|
children: [
|
||||||
|
%{
|
||||||
|
key: :threshold,
|
||||||
|
type: :integer,
|
||||||
|
description: "Required age (in seconds) of a post before actions are taken.",
|
||||||
|
suggestions: [172_800]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :actions,
|
||||||
|
type: {:list, :atom},
|
||||||
|
description:
|
||||||
|
"A list of actions to apply to the post. `:delist` removes the post from public timelines; " <>
|
||||||
|
"`:strip_followers` removes followers from the ActivityPub recipient list ensuring they won't be delivered to home timelines; " <>
|
||||||
|
"`:reject` rejects the message entirely",
|
||||||
|
suggestions: [:delist, :strip_followers, :reject]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -48,4 +48,27 @@ def filter(object), do: {:ok, object}
|
||||||
@impl true
|
@impl true
|
||||||
def describe,
|
def describe,
|
||||||
do: {:ok, %{mrf_rejectnonpublic: Config.get(:mrf_rejectnonpublic) |> Enum.into(%{})}}
|
do: {:ok, %{mrf_rejectnonpublic: Config.get(:mrf_rejectnonpublic) |> Enum.into(%{})}}
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def config_description do
|
||||||
|
%{
|
||||||
|
key: :mrf_rejectnonpublic,
|
||||||
|
related_policy: "Pleroma.Web.ActivityPub.MRF.RejectNonPublic",
|
||||||
|
description: "RejectNonPublic drops posts with non-public visibility settings.",
|
||||||
|
label: "MRF Reject Non Public",
|
||||||
|
children: [
|
||||||
|
%{
|
||||||
|
key: :allow_followersonly,
|
||||||
|
label: "Allow followers-only",
|
||||||
|
type: :boolean,
|
||||||
|
description: "Whether to allow followers-only posts"
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :allow_direct,
|
||||||
|
type: :boolean,
|
||||||
|
description: "Whether to allow direct messages"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -244,4 +244,78 @@ def describe do
|
||||||
|
|
||||||
{:ok, %{mrf_simple: mrf_simple}}
|
{:ok, %{mrf_simple: mrf_simple}}
|
||||||
end
|
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,
|
||||||
|
type: {:list, :string},
|
||||||
|
description: "List of instances to strip media attachments from",
|
||||||
|
suggestions: ["example.com", "*.example.com"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
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"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :federated_timeline_removal,
|
||||||
|
type: {:list, :string},
|
||||||
|
description:
|
||||||
|
"List of instances to remove from the Federated (aka The Whole Known Network) Timeline",
|
||||||
|
suggestions: ["example.com", "*.example.com"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :reject,
|
||||||
|
type: {:list, :string},
|
||||||
|
description: "List of instances to reject activities from (except deletes)",
|
||||||
|
suggestions: ["example.com", "*.example.com"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :accept,
|
||||||
|
type: {:list, :string},
|
||||||
|
description: "List of instances to only accept activities from (except deletes)",
|
||||||
|
suggestions: ["example.com", "*.example.com"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :followers_only,
|
||||||
|
type: {:list, :string},
|
||||||
|
description: "Force posts from the given instances to be visible by followers only",
|
||||||
|
suggestions: ["example.com", "*.example.com"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :report_removal,
|
||||||
|
type: {:list, :string},
|
||||||
|
description: "List of instances to reject reports from",
|
||||||
|
suggestions: ["example.com", "*.example.com"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :avatar_removal,
|
||||||
|
type: {:list, :string},
|
||||||
|
description: "List of instances to strip avatars from",
|
||||||
|
suggestions: ["example.com", "*.example.com"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :banner_removal,
|
||||||
|
type: {:list, :string},
|
||||||
|
description: "List of instances to strip banners from",
|
||||||
|
suggestions: ["example.com", "*.example.com"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :reject_deletes,
|
||||||
|
type: {:list, :string},
|
||||||
|
description: "List of instances to reject deletions from",
|
||||||
|
suggestions: ["example.com", "*.example.com"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -39,4 +39,28 @@ def filter(message), do: {:ok, message}
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def describe, do: {:ok, %{}}
|
def describe, do: {:ok, %{}}
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def config_description do
|
||||||
|
%{
|
||||||
|
key: :mrf_subchain,
|
||||||
|
related_policy: "Pleroma.Web.ActivityPub.MRF.SubchainPolicy",
|
||||||
|
label: "MRF Subchain",
|
||||||
|
description:
|
||||||
|
"This policy processes messages through an alternate pipeline when a given message matches certain criteria." <>
|
||||||
|
" All criteria are configured as a map of regular expressions to lists of policy modules.",
|
||||||
|
children: [
|
||||||
|
%{
|
||||||
|
key: :match_actor,
|
||||||
|
type: {:map, {:list, :string}},
|
||||||
|
description: "Matches a series of regular expressions against the actor field",
|
||||||
|
suggestions: [
|
||||||
|
%{
|
||||||
|
~r/https:\/\/example.com/s => [Pleroma.Web.ActivityPub.MRF.DropPolicy]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -41,4 +41,25 @@ def describe do
|
||||||
|
|
||||||
{:ok, %{mrf_user_allowlist: mrf_user_allowlist}}
|
{:ok, %{mrf_user_allowlist: mrf_user_allowlist}}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# TODO: change way of getting settings on `lib/pleroma/web/activity_pub/mrf/user_allow_list_policy.ex:18` to use `hosts` subkey
|
||||||
|
# @impl true
|
||||||
|
# def config_description do
|
||||||
|
# %{
|
||||||
|
# key: :mrf_user_allowlist,
|
||||||
|
# related_policy: "Pleroma.Web.ActivityPub.MRF.UserAllowListPolicy",
|
||||||
|
# description: "Accept-list of users from specified instances",
|
||||||
|
# children: [
|
||||||
|
# %{
|
||||||
|
# key: :hosts,
|
||||||
|
# type: :map,
|
||||||
|
# description:
|
||||||
|
# "The keys in this section are the domain names that the policy should apply to." <>
|
||||||
|
# " Each key should be assigned a list of users that should be allowed " <>
|
||||||
|
# "through by their ActivityPub ID",
|
||||||
|
# suggestions: [%{"example.org" => ["https://example.org/users/admin"]}]
|
||||||
|
# }
|
||||||
|
# ]
|
||||||
|
# }
|
||||||
|
# end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.VocabularyPolicy do
|
||||||
|
|
||||||
@behaviour Pleroma.Web.ActivityPub.MRF
|
@behaviour Pleroma.Web.ActivityPub.MRF
|
||||||
|
|
||||||
|
@impl true
|
||||||
def filter(%{"type" => "Undo", "object" => child_message} = message) do
|
def filter(%{"type" => "Undo", "object" => child_message} = message) do
|
||||||
with {:ok, _} <- filter(child_message) do
|
with {:ok, _} <- filter(child_message) do
|
||||||
{:ok, message}
|
{:ok, message}
|
||||||
|
@ -36,6 +37,33 @@ def filter(%{"type" => message_type} = message) do
|
||||||
|
|
||||||
def filter(message), do: {:ok, message}
|
def filter(message), do: {:ok, message}
|
||||||
|
|
||||||
|
@impl true
|
||||||
def describe,
|
def describe,
|
||||||
do: {:ok, %{mrf_vocabulary: Pleroma.Config.get(:mrf_vocabulary) |> Enum.into(%{})}}
|
do: {:ok, %{mrf_vocabulary: Pleroma.Config.get(:mrf_vocabulary) |> Enum.into(%{})}}
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def config_description do
|
||||||
|
%{
|
||||||
|
key: :mrf_vocabulary,
|
||||||
|
related_policy: "Pleroma.Web.ActivityPub.MRF.VocabularyPolicy",
|
||||||
|
label: "MRF Vocabulary",
|
||||||
|
description: "Filter messages which belong to certain activity vocabularies",
|
||||||
|
children: [
|
||||||
|
%{
|
||||||
|
key: :accept,
|
||||||
|
type: {:list, :string},
|
||||||
|
description:
|
||||||
|
"A list of ActivityStreams terms to accept. If empty, all supported messages are accepted.",
|
||||||
|
suggestions: ["Create", "Follow", "Mention", "Announce", "Like"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :reject,
|
||||||
|
type: {:list, :string},
|
||||||
|
description:
|
||||||
|
"A list of ActivityStreams terms to reject. If empty, no messages are rejected.",
|
||||||
|
suggestions: ["Create", "Follow", "Mention", "Announce", "Like"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
19
test/fixtures/modules/good_mrf.ex
vendored
Normal file
19
test/fixtures/modules/good_mrf.ex
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
defmodule Fixtures.Modules.GoodMRF do
|
||||||
|
@behaviour Pleroma.Web.ActivityPub.MRF
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def filter(a), do: {:ok, a}
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def describe, do: %{}
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def config_description do
|
||||||
|
%{
|
||||||
|
key: :good_mrf,
|
||||||
|
related_policy: "Fixtures.Modules.GoodMRF",
|
||||||
|
label: "Good MRF",
|
||||||
|
description: "Some description"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
|
@ -87,4 +87,20 @@ test "it works as expected with mock policy" do
|
||||||
{:ok, ^expected} = MRF.describe()
|
{:ok, ^expected} = MRF.describe()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "config_descriptions/0" do
|
||||||
|
descriptions = MRF.config_descriptions()
|
||||||
|
|
||||||
|
good_mrf = Enum.find(descriptions, fn %{key: key} -> key == :good_mrf end)
|
||||||
|
|
||||||
|
assert good_mrf == %{
|
||||||
|
key: :good_mrf,
|
||||||
|
related_policy: "Fixtures.Modules.GoodMRF",
|
||||||
|
label: "Good MRF",
|
||||||
|
description: "Some description",
|
||||||
|
group: :pleroma,
|
||||||
|
tab: :mrf,
|
||||||
|
type: :group
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue