Merge branch 'feature/1631-redesign-mrf-configuration' into 'develop'

Moving mrf settings from instance to separate mrf group

Closes #1631

See merge request pleroma/pleroma!2320
This commit is contained in:
Haelwenn 2020-06-23 16:38:27 +00:00
commit c7d69e9256
19 changed files with 257 additions and 127 deletions

View file

@ -11,6 +11,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Using the `only_media` filter on timelines will now exclude reblog media - Using the `only_media` filter on timelines will now exclude reblog media
- MFR policy to set global expiration for all local Create activities - MFR policy to set global expiration for all local Create activities
- OGP rich media parser merged with TwitterCard - OGP rich media parser merged with TwitterCard
- Configuration: `:instance, rewrite_policy` moved to `:mrf, policies`, `:instance, :mrf_transparency` moved to `:mrf, :transparency`, `:instance, :mrf_transparency_exclusions` moved to `:mrf, :transparency_exclusions`. Old config namespace is deprecated.
<details> <details>
<summary>API Changes</summary> <summary>API Changes</summary>
- **Breaking:** Emoji API: changed methods and renamed routes. - **Breaking:** Emoji API: changed methods and renamed routes.

View file

@ -210,7 +210,6 @@
Pleroma.Web.ActivityPub.Publisher Pleroma.Web.ActivityPub.Publisher
], ],
allow_relay: true, allow_relay: true,
rewrite_policy: Pleroma.Web.ActivityPub.MRF.NoOpPolicy,
public: true, public: true,
quarantined_instances: [], quarantined_instances: [],
managed_config: true, managed_config: true,
@ -221,8 +220,6 @@
"text/markdown", "text/markdown",
"text/bbcode" "text/bbcode"
], ],
mrf_transparency: true,
mrf_transparency_exclusions: [],
autofollowed_nicknames: [], autofollowed_nicknames: [],
max_pinned_statuses: 1, max_pinned_statuses: 1,
attachment_links: false, attachment_links: false,
@ -693,6 +690,11 @@
config :pleroma, Pleroma.Web.ApiSpec.CastAndValidate, strict: false config :pleroma, Pleroma.Web.ApiSpec.CastAndValidate, strict: false
config :pleroma, :mrf,
policies: Pleroma.Web.ActivityPub.MRF.NoOpPolicy,
transparency: true,
transparency_exclusions: []
# Import environment specific config. This must remain at the bottom # Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above. # of this file so it overrides the configuration defined above.
import_config "#{Mix.env()}.exs" import_config "#{Mix.env()}.exs"

View file

@ -689,17 +689,6 @@
type: :boolean, type: :boolean,
description: "Enable Pleroma's Relay, which makes it possible to follow a whole instance" description: "Enable Pleroma's Relay, which makes it possible to follow a whole instance"
}, },
%{
key: :rewrite_policy,
type: [:module, {:list, :module}],
description:
"A list of enabled MRF policies. Module names are shortened (removed leading `Pleroma.Web.ActivityPub.MRF.` part), but on adding custom module you need to use full name.",
suggestions:
Generator.list_modules_in_dir(
"lib/pleroma/web/activity_pub/mrf",
"Elixir.Pleroma.Web.ActivityPub.MRF."
)
},
%{ %{
key: :public, key: :public,
type: :boolean, type: :boolean,
@ -742,23 +731,6 @@
"text/bbcode" "text/bbcode"
] ]
}, },
%{
key: :mrf_transparency,
label: "MRF transparency",
type: :boolean,
description:
"Make the content of your Message Rewrite Facility settings public (via nodeinfo)"
},
%{
key: :mrf_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"
]
},
%{ %{
key: :extended_nickname_format, key: :extended_nickname_format,
type: :boolean, type: :boolean,
@ -3389,5 +3361,41 @@
suggestions: [false] suggestions: [false]
} }
] ]
},
%{
group: :pleroma,
key: :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:
Generator.list_modules_in_dir(
"lib/pleroma/web/activity_pub/mrf",
"Elixir.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"
]
}
]
} }
] ]

View file

@ -36,26 +36,10 @@ To add configuration to your config file, you can copy it from the base config.
* `federation_incoming_replies_max_depth`: Max. depth of reply-to activities fetching on incoming federation, to prevent out-of-memory situations while fetching very long threads. If set to `nil`, threads of any depth will be fetched. Lower this value if you experience out-of-memory crashes. * `federation_incoming_replies_max_depth`: Max. depth of reply-to activities fetching on incoming federation, to prevent out-of-memory situations while fetching very long threads. If set to `nil`, threads of any depth will be fetched. Lower this value if you experience out-of-memory crashes.
* `federation_reachability_timeout_days`: Timeout (in days) of each external federation target being unreachable prior to pausing federating to it. * `federation_reachability_timeout_days`: Timeout (in days) of each external federation target being unreachable prior to pausing federating to it.
* `allow_relay`: Enable Pleromas Relay, which makes it possible to follow a whole instance. * `allow_relay`: Enable Pleromas Relay, which makes it possible to follow a whole instance.
* `rewrite_policy`: Message Rewrite Policy, either one or a list. Here are the ones available by default:
* `Pleroma.Web.ActivityPub.MRF.NoOpPolicy`: Doesnt modify activities (default).
* `Pleroma.Web.ActivityPub.MRF.DropPolicy`: Drops all activities. It generally doesnt makes sense to use in production.
* `Pleroma.Web.ActivityPub.MRF.SimplePolicy`: Restrict the visibility of activities from certain instances (See [`:mrf_simple`](#mrf_simple)).
* `Pleroma.Web.ActivityPub.MRF.TagPolicy`: Applies policies to individual users based on tags, which can be set using pleroma-fe/admin-fe/any other app that supports Pleroma Admin API. For example it allows marking posts from individual users nsfw (sensitive).
* `Pleroma.Web.ActivityPub.MRF.SubchainPolicy`: Selectively runs other MRF policies when messages match (See [`:mrf_subchain`](#mrf_subchain)).
* `Pleroma.Web.ActivityPub.MRF.RejectNonPublic`: Drops posts with non-public visibility settings (See [`:mrf_rejectnonpublic`](#mrf_rejectnonpublic)).
* `Pleroma.Web.ActivityPub.MRF.EnsureRePrepended`: Rewrites posts to ensure that replies to posts with subjects do not have an identical subject and instead begin with re:.
* `Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicy`: Rejects posts from likely spambots by rejecting posts from new users that contain links.
* `Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy`: Crawls attachments using their MediaProxy URLs so that the MediaProxy cache is primed.
* `Pleroma.Web.ActivityPub.MRF.MentionPolicy`: Drops posts mentioning configurable users. (See [`:mrf_mention`](#mrf_mention)).
* `Pleroma.Web.ActivityPub.MRF.VocabularyPolicy`: Restricts activities to a configured set of vocabulary. (See [`:mrf_vocabulary`](#mrf_vocabulary)).
* `Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy`: Rejects or delists posts based on their age when received. (See [`:mrf_object_age`](#mrf_object_age)).
* `Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy`: Adds expiration to all local Create activities (see [`:mrf_activity_expiration`](#mrf_activity_expiration)).
* `public`: Makes the client API in authenticated mode-only except for user-profiles. Useful for disabling the Local Timeline and The Whole Known Network. * `public`: Makes the client API in authenticated mode-only except for user-profiles. Useful for disabling the Local Timeline and The Whole Known Network.
* `quarantined_instances`: List of ActivityPub instances where private(DMs, followers-only) activities will not be send. * `quarantined_instances`: List of ActivityPub instances where private(DMs, followers-only) activities will not be send.
* `managed_config`: Whenether the config for pleroma-fe is configured in [:frontend_configurations](#frontend_configurations) or in ``static/config.json``. * `managed_config`: Whenether the config for pleroma-fe is configured in [:frontend_configurations](#frontend_configurations) or in ``static/config.json``.
* `allowed_post_formats`: MIME-type list of formats allowed to be posted (transformed into HTML). * `allowed_post_formats`: MIME-type list of formats allowed to be posted (transformed into HTML).
* `mrf_transparency`: Make the content of your Message Rewrite Facility settings public (via nodeinfo).
* `mrf_transparency_exclusions`: Exclude specific instance names from MRF transparency. The use of the exclusions feature will be disclosed in nodeinfo as a boolean value.
* `extended_nickname_format`: Set to `true` to use extended local nicknames format (allows underscores/dashes). This will break federation with * `extended_nickname_format`: Set to `true` to use extended local nicknames format (allows underscores/dashes). This will break federation with
older software for theses nicknames. older software for theses nicknames.
* `max_pinned_statuses`: The maximum number of pinned statuses. `0` will disable the feature. * `max_pinned_statuses`: The maximum number of pinned statuses. `0` will disable the feature.
@ -78,11 +62,30 @@ To add configuration to your config file, you can copy it from the base config.
* `external_user_synchronization`: Enabling following/followers counters synchronization for external users. * `external_user_synchronization`: Enabling following/followers counters synchronization for external users.
* `cleanup_attachments`: Remove attachments along with statuses. Does not affect duplicate files and attachments without status. Enabling this will increase load to database when deleting statuses on larger instances. * `cleanup_attachments`: Remove attachments along with statuses. Does not affect duplicate files and attachments without status. Enabling this will increase load to database when deleting statuses on larger instances.
## Message rewrite facility
### :mrf
* `policies`: Message Rewrite Policy, either one or a list. Here are the ones available by default:
* `Pleroma.Web.ActivityPub.MRF.NoOpPolicy`: Doesnt modify activities (default).
* `Pleroma.Web.ActivityPub.MRF.DropPolicy`: Drops all activities. It generally doesnt makes sense to use in production.
* `Pleroma.Web.ActivityPub.MRF.SimplePolicy`: Restrict the visibility of activities from certains instances (See [`:mrf_simple`](#mrf_simple)).
* `Pleroma.Web.ActivityPub.MRF.TagPolicy`: Applies policies to individual users based on tags, which can be set using pleroma-fe/admin-fe/any other app that supports Pleroma Admin API. For example it allows marking posts from individual users nsfw (sensitive).
* `Pleroma.Web.ActivityPub.MRF.SubchainPolicy`: Selectively runs other MRF policies when messages match (See [`:mrf_subchain`](#mrf_subchain)).
* `Pleroma.Web.ActivityPub.MRF.RejectNonPublic`: Drops posts with non-public visibility settings (See [`:mrf_rejectnonpublic`](#mrf_rejectnonpublic)).
* `Pleroma.Web.ActivityPub.MRF.EnsureRePrepended`: Rewrites posts to ensure that replies to posts with subjects do not have an identical subject and instead begin with re:.
* `Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicy`: Rejects posts from likely spambots by rejecting posts from new users that contain links.
* `Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy`: Crawls attachments using their MediaProxy URLs so that the MediaProxy cache is primed.
* `Pleroma.Web.ActivityPub.MRF.MentionPolicy`: Drops posts mentioning configurable users. (See [`:mrf_mention`](#mrf_mention)).
* `Pleroma.Web.ActivityPub.MRF.VocabularyPolicy`: Restricts activities to a configured set of vocabulary. (See [`:mrf_vocabulary`](#mrf_vocabulary)).
* `Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy`: Rejects or delists posts based on their age when received. (See [`:mrf_object_age`](#mrf_object_age)).
* `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.
## Federation ## Federation
### MRF policies ### MRF policies
!!! note !!! note
Configuring MRF policies is not enough for them to take effect. You have to enable them by specifying their module in `rewrite_policy` under [:instance](#instance) section. Configuring MRF policies is not enough for them to take effect. You have to enable them by specifying their module in `policies` under [:mrf](#mrf) section.
#### :mrf_simple #### :mrf_simple
* `media_removal`: List of instances to remove media from. * `media_removal`: List of instances to remove media from.
@ -969,13 +972,13 @@ config :pleroma, :database_config_whitelist, [
Restrict access for unauthenticated users to timelines (public and federate), user profiles and statuses. Restrict access for unauthenticated users to timelines (public and federate), user profiles and statuses.
* `timelines` - public and federated timelines * `timelines`: public and federated timelines
* `local` - public timeline * `local`: public timeline
* `federated` * `federated`
* `profiles` - user profiles * `profiles`: user profiles
* `local` * `local`
* `remote` * `remote`
* `activities` - statuses * `activities`: statuses
* `local` * `local`
* `remote` * `remote`

View file

@ -34,9 +34,9 @@ config :pleroma, :instance,
To use `SimplePolicy`, you must enable it. Do so by adding the following to your `:instance` config object, so that it looks like this: To use `SimplePolicy`, you must enable it. Do so by adding the following to your `:instance` config object, so that it looks like this:
```elixir ```elixir
config :pleroma, :instance, config :pleroma, :mrf,
[...] [...]
rewrite_policy: Pleroma.Web.ActivityPub.MRF.SimplePolicy policies: Pleroma.Web.ActivityPub.MRF.SimplePolicy
``` ```
Once `SimplePolicy` is enabled, you can configure various groups in the `:mrf_simple` config object. These groups are: Once `SimplePolicy` is enabled, you can configure various groups in the `:mrf_simple` config object. These groups are:
@ -58,8 +58,8 @@ Servers should be configured as lists.
This example will enable `SimplePolicy`, block media from `illegalporn.biz`, mark media as NSFW from `porn.biz` and `porn.business`, reject messages from `spam.com`, remove messages from `spam.university` from the federated timeline and block reports (flags) from `whiny.whiner`: This example will enable `SimplePolicy`, block media from `illegalporn.biz`, mark media as NSFW from `porn.biz` and `porn.business`, reject messages from `spam.com`, remove messages from `spam.university` from the federated timeline and block reports (flags) from `whiny.whiner`:
```elixir ```elixir
config :pleroma, :instance, config :pleroma, :mrf,
rewrite_policy: [Pleroma.Web.ActivityPub.MRF.SimplePolicy] policies: [Pleroma.Web.ActivityPub.MRF.SimplePolicy]
config :pleroma, :mrf_simple, config :pleroma, :mrf_simple,
media_removal: ["illegalporn.biz"], media_removal: ["illegalporn.biz"],
@ -75,7 +75,7 @@ The effects of MRF policies can be very drastic. It is important to use this fun
## Writing your own MRF Policy ## Writing your own MRF Policy
As discussed above, the MRF system is a modular system that supports pluggable policies. This means that an admin may write a custom MRF policy in Elixir or any other language that runs on the Erlang VM, by specifying the module name in the `rewrite_policy` config setting. As discussed above, the MRF system is a modular system that supports pluggable policies. This means that an admin may write a custom MRF policy in Elixir or any other language that runs on the Erlang VM, by specifying the module name in the `policies` config setting.
For example, here is a sample policy module which rewrites all messages to "new message content": For example, here is a sample policy module which rewrites all messages to "new message content":
@ -125,8 +125,8 @@ end
If you save this file as `lib/pleroma/web/activity_pub/mrf/rewrite_policy.ex`, it will be included when you next rebuild Pleroma. You can enable it in the configuration like so: If you save this file as `lib/pleroma/web/activity_pub/mrf/rewrite_policy.ex`, it will be included when you next rebuild Pleroma. You can enable it in the configuration like so:
```elixir ```elixir
config :pleroma, :instance, config :pleroma, :mrf,
rewrite_policy: [ policies: [
Pleroma.Web.ActivityPub.MRF.SimplePolicy, Pleroma.Web.ActivityPub.MRF.SimplePolicy,
Pleroma.Web.ActivityPub.MRF.RewritePolicy Pleroma.Web.ActivityPub.MRF.RewritePolicy
] ]

View file

@ -33,6 +33,6 @@ as soon as the post is received by your instance.
Add to your `prod.secret.exs`: Add to your `prod.secret.exs`:
``` ```
config :pleroma, :instance, config :pleroma, :mrf,
rewrite_policy: [Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy] policies: [Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy]
``` ```

View file

@ -167,7 +167,9 @@ defp only_full_update?(%ConfigDB{group: group, key: key}) do
end) end)
end end
@spec delete(map()) :: {:ok, ConfigDB.t()} | {:error, Changeset.t()} @spec delete(ConfigDB.t() | map()) :: {:ok, ConfigDB.t()} | {:error, Changeset.t()}
def delete(%ConfigDB{} = config), do: Repo.delete(config)
def delete(params) do def delete(params) do
search_opts = Map.delete(params, :subkeys) search_opts = Map.delete(params, :subkeys)

View file

@ -3,9 +3,23 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Config.DeprecationWarnings do defmodule Pleroma.Config.DeprecationWarnings do
alias Pleroma.Config
require Logger require Logger
alias Pleroma.Config alias Pleroma.Config
@type config_namespace() :: [atom()]
@type config_map() :: {config_namespace(), config_namespace(), String.t()}
@mrf_config_map [
{[:instance, :rewrite_policy], [:mrf, :policies],
"\n* `config :pleroma, :instance, rewrite_policy` is now `config :pleroma, :mrf, policies`"},
{[:instance, :mrf_transparency], [:mrf, :transparency],
"\n* `config :pleroma, :instance, mrf_transparency` is now `config :pleroma, :mrf, transparency`"},
{[:instance, :mrf_transparency_exclusions], [:mrf, :transparency_exclusions],
"\n* `config :pleroma, :instance, mrf_transparency_exclusions` is now `config :pleroma, :mrf, transparency_exclusions`"}
]
def check_hellthread_threshold do def check_hellthread_threshold do
if Config.get([:mrf_hellthread, :threshold]) do if Config.get([:mrf_hellthread, :threshold]) do
Logger.warn(""" Logger.warn("""
@ -39,5 +53,35 @@ def mrf_user_allowlist do
def warn do def warn do
check_hellthread_threshold() check_hellthread_threshold()
mrf_user_allowlist() mrf_user_allowlist()
check_old_mrf_config()
end
def check_old_mrf_config do
warning_preface = """
!!!DEPRECATION WARNING!!!
Your config is using old namespaces for MRF configuration. They should work for now, but you are advised to change to new namespaces to prevent possible issues later:
"""
move_namespace_and_warn(@mrf_config_map, warning_preface)
end
@spec move_namespace_and_warn([config_map()], String.t()) :: :ok
def move_namespace_and_warn(config_map, warning_preface) do
warning =
Enum.reduce(config_map, "", fn
{old, new, err_msg}, acc ->
old_config = Config.get(old)
if old_config do
Config.put(new, old_config)
acc <> err_msg
else
acc
end
end)
if warning != "" do
Logger.warn(warning_preface <> warning)
end
end end
end end

View file

@ -16,7 +16,7 @@ def filter(policies, %{} = object) do
def filter(%{} = object), do: get_policies() |> filter(object) def filter(%{} = object), do: get_policies() |> filter(object)
def get_policies do def get_policies do
Pleroma.Config.get([:instance, :rewrite_policy], []) |> get_policies() Pleroma.Config.get([:mrf, :policies], []) |> get_policies()
end end
defp get_policies(policy) when is_atom(policy), do: [policy] defp get_policies(policy) when is_atom(policy), do: [policy]
@ -51,7 +51,7 @@ def describe(policies) do
get_policies() get_policies()
|> Enum.map(fn policy -> to_string(policy) |> String.split(".") |> List.last() end) |> Enum.map(fn policy -> to_string(policy) |> String.split(".") |> List.last() end)
exclusions = Pleroma.Config.get([:instance, :mrf_transparency_exclusions]) exclusions = Pleroma.Config.get([:mrf, :transparency_exclusions])
base = base =
%{ %{

View file

@ -3,21 +3,23 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
alias Pleroma.User
alias Pleroma.Web.ActivityPub.MRF
@moduledoc "Filter activities depending on their origin instance" @moduledoc "Filter activities depending on their origin instance"
@behaviour Pleroma.Web.ActivityPub.MRF @behaviour Pleroma.Web.ActivityPub.MRF
alias Pleroma.Config
alias Pleroma.User
alias Pleroma.Web.ActivityPub.MRF
require Pleroma.Constants require Pleroma.Constants
defp check_accept(%{host: actor_host} = _actor_info, object) do defp check_accept(%{host: actor_host} = _actor_info, object) do
accepts = accepts =
Pleroma.Config.get([:mrf_simple, :accept]) Config.get([:mrf_simple, :accept])
|> MRF.subdomains_regex() |> MRF.subdomains_regex()
cond do cond do
accepts == [] -> {:ok, object} accepts == [] -> {:ok, object}
actor_host == Pleroma.Config.get([Pleroma.Web.Endpoint, :url, :host]) -> {:ok, object} actor_host == Config.get([Pleroma.Web.Endpoint, :url, :host]) -> {:ok, object}
MRF.subdomain_match?(accepts, actor_host) -> {:ok, object} MRF.subdomain_match?(accepts, actor_host) -> {:ok, object}
true -> {:reject, nil} true -> {:reject, nil}
end end
@ -25,7 +27,7 @@ defp check_accept(%{host: actor_host} = _actor_info, object) do
defp check_reject(%{host: actor_host} = _actor_info, object) do defp check_reject(%{host: actor_host} = _actor_info, object) do
rejects = rejects =
Pleroma.Config.get([:mrf_simple, :reject]) Config.get([:mrf_simple, :reject])
|> MRF.subdomains_regex() |> MRF.subdomains_regex()
if MRF.subdomain_match?(rejects, actor_host) do if MRF.subdomain_match?(rejects, actor_host) do
@ -41,7 +43,7 @@ defp check_media_removal(
) )
when length(child_attachment) > 0 do when length(child_attachment) > 0 do
media_removal = media_removal =
Pleroma.Config.get([:mrf_simple, :media_removal]) Config.get([:mrf_simple, :media_removal])
|> MRF.subdomains_regex() |> MRF.subdomains_regex()
object = object =
@ -65,7 +67,7 @@ defp check_media_nsfw(
} = object } = object
) do ) do
media_nsfw = media_nsfw =
Pleroma.Config.get([:mrf_simple, :media_nsfw]) Config.get([:mrf_simple, :media_nsfw])
|> MRF.subdomains_regex() |> MRF.subdomains_regex()
object = object =
@ -85,7 +87,7 @@ defp check_media_nsfw(_actor_info, object), do: {:ok, object}
defp check_ftl_removal(%{host: actor_host} = _actor_info, object) do defp check_ftl_removal(%{host: actor_host} = _actor_info, object) do
timeline_removal = timeline_removal =
Pleroma.Config.get([:mrf_simple, :federated_timeline_removal]) Config.get([:mrf_simple, :federated_timeline_removal])
|> MRF.subdomains_regex() |> MRF.subdomains_regex()
object = object =
@ -108,7 +110,7 @@ defp check_ftl_removal(%{host: actor_host} = _actor_info, object) do
defp check_report_removal(%{host: actor_host} = _actor_info, %{"type" => "Flag"} = object) do defp check_report_removal(%{host: actor_host} = _actor_info, %{"type" => "Flag"} = object) do
report_removal = report_removal =
Pleroma.Config.get([:mrf_simple, :report_removal]) Config.get([:mrf_simple, :report_removal])
|> MRF.subdomains_regex() |> MRF.subdomains_regex()
if MRF.subdomain_match?(report_removal, actor_host) do if MRF.subdomain_match?(report_removal, actor_host) do
@ -122,7 +124,7 @@ defp check_report_removal(_actor_info, object), do: {:ok, object}
defp check_avatar_removal(%{host: actor_host} = _actor_info, %{"icon" => _icon} = object) do defp check_avatar_removal(%{host: actor_host} = _actor_info, %{"icon" => _icon} = object) do
avatar_removal = avatar_removal =
Pleroma.Config.get([:mrf_simple, :avatar_removal]) Config.get([:mrf_simple, :avatar_removal])
|> MRF.subdomains_regex() |> MRF.subdomains_regex()
if MRF.subdomain_match?(avatar_removal, actor_host) do if MRF.subdomain_match?(avatar_removal, actor_host) do
@ -136,7 +138,7 @@ defp check_avatar_removal(_actor_info, object), do: {:ok, object}
defp check_banner_removal(%{host: actor_host} = _actor_info, %{"image" => _image} = object) do defp check_banner_removal(%{host: actor_host} = _actor_info, %{"image" => _image} = object) do
banner_removal = banner_removal =
Pleroma.Config.get([:mrf_simple, :banner_removal]) Config.get([:mrf_simple, :banner_removal])
|> MRF.subdomains_regex() |> MRF.subdomains_regex()
if MRF.subdomain_match?(banner_removal, actor_host) do if MRF.subdomain_match?(banner_removal, actor_host) do
@ -197,10 +199,10 @@ def filter(object), do: {:ok, object}
@impl true @impl true
def describe do def describe do
exclusions = Pleroma.Config.get([:instance, :mrf_transparency_exclusions]) exclusions = Config.get([:mrf, :transparency_exclusions])
mrf_simple = mrf_simple =
Pleroma.Config.get(:mrf_simple) Config.get(:mrf_simple)
|> Enum.map(fn {k, v} -> {k, Enum.reject(v, fn v -> v in exclusions end)} end) |> Enum.map(fn {k, v} -> {k, Enum.reject(v, fn v -> v in exclusions end)} end)
|> Enum.into(%{}) |> Enum.into(%{})

View file

@ -78,7 +78,7 @@ def features do
def federation do def federation do
quarantined = Config.get([:instance, :quarantined_instances], []) quarantined = Config.get([:instance, :quarantined_instances], [])
if Config.get([:instance, :mrf_transparency]) do if Config.get([:mrf, :transparency]) do
{:ok, data} = MRF.describe() {:ok, data} = MRF.describe()
data data

View file

@ -0,0 +1,39 @@
defmodule Pleroma.Repo.Migrations.MrfConfigMoveFromInstanceNamespace do
use Ecto.Migration
alias Pleroma.ConfigDB
@old_keys [:rewrite_policy, :mrf_transparency, :mrf_transparency_exclusions]
def change do
config = ConfigDB.get_by_params(%{group: ":pleroma", key: ":instance"})
if config do
old_instance = ConfigDB.from_binary(config.value)
mrf =
old_instance
|> Keyword.take(@old_keys)
|> Keyword.new(fn
{:rewrite_policy, policies} -> {:policies, policies}
{:mrf_transparency, transparency} -> {:transparency, transparency}
{:mrf_transparency_exclusions, exclusions} -> {:transparency_exclusions, exclusions}
end)
if mrf != [] do
{:ok, _} =
ConfigDB.create(
%{group: ":pleroma", key: ":mrf", value: ConfigDB.to_binary(mrf)},
false
)
new_instance = Keyword.drop(old_instance, @old_keys)
if new_instance != [] do
{:ok, _} = ConfigDB.update(config, %{value: ConfigDB.to_binary(new_instance)}, false)
else
{:ok, _} = ConfigDB.delete(config)
end
end
end
end
end

View file

@ -0,0 +1,57 @@
defmodule Pleroma.Config.DeprecationWarningsTest do
use ExUnit.Case, async: true
use Pleroma.Tests.Helpers
import ExUnit.CaptureLog
test "check_old_mrf_config/0" do
clear_config([:instance, :rewrite_policy], Pleroma.Web.ActivityPub.MRF.NoOpPolicy)
clear_config([:instance, :mrf_transparency], true)
clear_config([:instance, :mrf_transparency_exclusions], [])
assert capture_log(fn -> Pleroma.Config.DeprecationWarnings.check_old_mrf_config() end) =~
"""
!!!DEPRECATION WARNING!!!
Your config is using old namespaces for MRF configuration. They should work for now, but you are advised to change to new namespaces to prevent possible issues later:
* `config :pleroma, :instance, rewrite_policy` is now `config :pleroma, :mrf, policies`
* `config :pleroma, :instance, mrf_transparency` is now `config :pleroma, :mrf, transparency`
* `config :pleroma, :instance, mrf_transparency_exclusions` is now `config :pleroma, :mrf, transparency_exclusions`
"""
end
test "move_namespace_and_warn/2" do
old_group1 = [:group, :key]
old_group2 = [:group, :key2]
old_group3 = [:group, :key3]
new_group1 = [:another_group, :key4]
new_group2 = [:another_group, :key5]
new_group3 = [:another_group, :key6]
clear_config(old_group1, 1)
clear_config(old_group2, 2)
clear_config(old_group3, 3)
clear_config(new_group1)
clear_config(new_group2)
clear_config(new_group3)
config_map = [
{old_group1, new_group1, "\n error :key"},
{old_group2, new_group2, "\n error :key2"},
{old_group3, new_group3, "\n error :key3"}
]
assert capture_log(fn ->
Pleroma.Config.DeprecationWarnings.move_namespace_and_warn(
config_map,
"Warning preface"
)
end) =~ "Warning preface\n error :key\n error :key2\n error :key3"
assert Pleroma.Config.get(new_group1) == 1
assert Pleroma.Config.get(new_group2) == 2
assert Pleroma.Config.get(new_group3) == 3
end
end

View file

@ -121,14 +121,11 @@ test "load a settings with large values and pass to file", %{temp_file: temp_fil
federation_reachability_timeout_days: 7, federation_reachability_timeout_days: 7,
federation_publisher_modules: [Pleroma.Web.ActivityPub.Publisher], federation_publisher_modules: [Pleroma.Web.ActivityPub.Publisher],
allow_relay: true, allow_relay: true,
rewrite_policy: Pleroma.Web.ActivityPub.MRF.NoOpPolicy,
public: true, public: true,
quarantined_instances: [], quarantined_instances: [],
managed_config: true, managed_config: true,
static_dir: "instance/static/", static_dir: "instance/static/",
allowed_post_formats: ["text/plain", "text/html", "text/markdown", "text/bbcode"], allowed_post_formats: ["text/plain", "text/html", "text/markdown", "text/bbcode"],
mrf_transparency: true,
mrf_transparency_exclusions: [],
autofollowed_nicknames: [], autofollowed_nicknames: [],
max_pinned_statuses: 1, max_pinned_statuses: 1,
attachment_links: false, attachment_links: false,
@ -175,7 +172,7 @@ test "load a settings with large values and pass to file", %{temp_file: temp_fil
end end
assert file == assert file ==
"#{header}\n\nconfig :pleroma, :instance,\n name: \"Pleroma\",\n email: \"example@example.com\",\n notify_email: \"noreply@example.com\",\n description: \"A Pleroma instance, an alternative fediverse server\",\n limit: 5000,\n chat_limit: 5000,\n remote_limit: 100_000,\n upload_limit: 16_000_000,\n avatar_upload_limit: 2_000_000,\n background_upload_limit: 4_000_000,\n banner_upload_limit: 4_000_000,\n poll_limits: %{\n max_expiration: 31_536_000,\n max_option_chars: 200,\n max_options: 20,\n min_expiration: 0\n },\n registrations_open: true,\n federating: true,\n federation_incoming_replies_max_depth: 100,\n federation_reachability_timeout_days: 7,\n federation_publisher_modules: [Pleroma.Web.ActivityPub.Publisher],\n allow_relay: true,\n rewrite_policy: Pleroma.Web.ActivityPub.MRF.NoOpPolicy,\n public: true,\n quarantined_instances: [],\n managed_config: true,\n static_dir: \"instance/static/\",\n allowed_post_formats: [\"text/plain\", \"text/html\", \"text/markdown\", \"text/bbcode\"],\n mrf_transparency: true,\n mrf_transparency_exclusions: [],\n autofollowed_nicknames: [],\n max_pinned_statuses: 1,\n attachment_links: false,\n welcome_user_nickname: nil,\n welcome_message: nil,\n max_report_comment_size: 1000,\n safe_dm_mentions: false,\n healthcheck: false,\n remote_post_retention_days: 90,\n skip_thread_containment: true,\n limit_to_local_content: :unauthenticated,\n user_bio_length: 5000,\n user_name_length: 100,\n max_account_fields: 10,\n max_remote_account_fields: 20,\n account_field_name_length: 512,\n account_field_value_length: 2048,\n external_user_synchronization: true,\n extended_nickname_format: true,\n multi_factor_authentication: [\n totp: [digits: 6, period: 30],\n backup_codes: [number: 2, length: 6]\n ]\n" "#{header}\n\nconfig :pleroma, :instance,\n name: \"Pleroma\",\n email: \"example@example.com\",\n notify_email: \"noreply@example.com\",\n description: \"A Pleroma instance, an alternative fediverse server\",\n limit: 5000,\n chat_limit: 5000,\n remote_limit: 100_000,\n upload_limit: 16_000_000,\n avatar_upload_limit: 2_000_000,\n background_upload_limit: 4_000_000,\n banner_upload_limit: 4_000_000,\n poll_limits: %{\n max_expiration: 31_536_000,\n max_option_chars: 200,\n max_options: 20,\n min_expiration: 0\n },\n registrations_open: true,\n federating: true,\n federation_incoming_replies_max_depth: 100,\n federation_reachability_timeout_days: 7,\n federation_publisher_modules: [Pleroma.Web.ActivityPub.Publisher],\n allow_relay: true,\n public: true,\n quarantined_instances: [],\n managed_config: true,\n static_dir: \"instance/static/\",\n allowed_post_formats: [\"text/plain\", \"text/html\", \"text/markdown\", \"text/bbcode\"],\n autofollowed_nicknames: [],\n max_pinned_statuses: 1,\n attachment_links: false,\n welcome_user_nickname: nil,\n welcome_message: nil,\n max_report_comment_size: 1000,\n safe_dm_mentions: false,\n healthcheck: false,\n remote_post_retention_days: 90,\n skip_thread_containment: true,\n limit_to_local_content: :unauthenticated,\n user_bio_length: 5000,\n user_name_length: 100,\n max_account_fields: 10,\n max_remote_account_fields: 20,\n account_field_name_length: 512,\n account_field_value_length: 2048,\n external_user_synchronization: true,\n extended_nickname_format: true,\n multi_factor_authentication: [\n totp: [digits: 6, period: 30],\n backup_codes: [number: 2, length: 6]\n ]\n"
end end
end end
end end

View file

@ -2055,11 +2055,11 @@ test "it just returns the input if the user has no following/follower addresses"
end end
describe "global activity expiration" do describe "global activity expiration" do
setup do: clear_config([:instance, :rewrite_policy]) setup do: clear_config([:mrf, :policies])
test "creates an activity expiration for local Create activities" do test "creates an activity expiration for local Create activities" do
Pleroma.Config.put( Pleroma.Config.put(
[:instance, :rewrite_policy], [:mrf, :policies],
Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy
) )

View file

@ -60,8 +60,6 @@ test "matches are case-insensitive" do
end end
describe "describe/0" do describe "describe/0" do
setup do: clear_config([:instance, :rewrite_policy])
test "it works as expected with noop policy" do test "it works as expected with noop policy" do
expected = %{ expected = %{
mrf_policies: ["NoOpPolicy"], mrf_policies: ["NoOpPolicy"],
@ -72,7 +70,7 @@ test "it works as expected with noop policy" do
end end
test "it works as expected with mock policy" do test "it works as expected with mock policy" do
Pleroma.Config.put([:instance, :rewrite_policy], [MRFModuleMock]) clear_config([:mrf, :policies], [MRFModuleMock])
expected = %{ expected = %{
mrf_policies: ["MRFModuleMock"], mrf_policies: ["MRFModuleMock"],

View file

@ -23,7 +23,7 @@ defmodule Pleroma.Web.FederatorTest do
setup_all do: clear_config([:instance, :federating], true) setup_all do: clear_config([:instance, :federating], true)
setup do: clear_config([:instance, :allow_relay]) setup do: clear_config([:instance, :allow_relay])
setup do: clear_config([:instance, :rewrite_policy]) setup do: clear_config([:mrf, :policies])
setup do: clear_config([:mrf_keyword]) setup do: clear_config([:mrf_keyword])
describe "Publish an activity" do describe "Publish an activity" do
@ -158,7 +158,7 @@ test "it does not crash if MRF rejects the post" do
Pleroma.Config.put([:mrf_keyword, :reject], ["lain"]) Pleroma.Config.put([:mrf_keyword, :reject], ["lain"])
Pleroma.Config.put( Pleroma.Config.put(
[:instance, :rewrite_policy], [:mrf, :policies],
Pleroma.Web.ActivityPub.MRF.KeywordPolicy Pleroma.Web.ActivityPub.MRF.KeywordPolicy
) )

View file

@ -67,10 +67,10 @@ test "returns software.repository field in nodeinfo 2.1", %{conn: conn} do
end end
test "returns fieldsLimits field", %{conn: conn} do test "returns fieldsLimits field", %{conn: conn} do
Config.put([:instance, :max_account_fields], 10) clear_config([:instance, :max_account_fields], 10)
Config.put([:instance, :max_remote_account_fields], 15) clear_config([:instance, :max_remote_account_fields], 15)
Config.put([:instance, :account_field_name_length], 255) clear_config([:instance, :account_field_name_length], 255)
Config.put([:instance, :account_field_value_length], 2048) clear_config([:instance, :account_field_value_length], 2048)
response = response =
conn conn
@ -84,8 +84,7 @@ test "returns fieldsLimits field", %{conn: conn} do
end end
test "it returns the safe_dm_mentions feature if enabled", %{conn: conn} do test "it returns the safe_dm_mentions feature if enabled", %{conn: conn} do
option = Config.get([:instance, :safe_dm_mentions]) clear_config([:instance, :safe_dm_mentions], true)
Config.put([:instance, :safe_dm_mentions], true)
response = response =
conn conn
@ -102,8 +101,6 @@ test "it returns the safe_dm_mentions feature if enabled", %{conn: conn} do
|> json_response(:ok) |> json_response(:ok)
refute "safe_dm_mentions" in response["metadata"]["features"] refute "safe_dm_mentions" in response["metadata"]["features"]
Config.put([:instance, :safe_dm_mentions], option)
end end
describe "`metadata/federation/enabled`" do describe "`metadata/federation/enabled`" do
@ -156,14 +153,11 @@ test "it shows default features flags", %{conn: conn} do
end end
test "it shows MRF transparency data if enabled", %{conn: conn} do test "it shows MRF transparency data if enabled", %{conn: conn} do
config = Config.get([:instance, :rewrite_policy]) clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.SimplePolicy])
Config.put([:instance, :rewrite_policy], [Pleroma.Web.ActivityPub.MRF.SimplePolicy]) clear_config([:mrf, :transparency], true)
option = Config.get([:instance, :mrf_transparency])
Config.put([:instance, :mrf_transparency], true)
simple_config = %{"reject" => ["example.com"]} simple_config = %{"reject" => ["example.com"]}
Config.put(:mrf_simple, simple_config) clear_config(:mrf_simple, simple_config)
response = response =
conn conn
@ -171,26 +165,17 @@ test "it shows MRF transparency data if enabled", %{conn: conn} do
|> json_response(:ok) |> json_response(:ok)
assert response["metadata"]["federation"]["mrf_simple"] == simple_config assert response["metadata"]["federation"]["mrf_simple"] == simple_config
Config.put([:instance, :rewrite_policy], config)
Config.put([:instance, :mrf_transparency], option)
Config.put(:mrf_simple, %{})
end end
test "it performs exclusions from MRF transparency data if configured", %{conn: conn} do test "it performs exclusions from MRF transparency data if configured", %{conn: conn} do
config = Config.get([:instance, :rewrite_policy]) clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.SimplePolicy])
Config.put([:instance, :rewrite_policy], [Pleroma.Web.ActivityPub.MRF.SimplePolicy]) clear_config([:mrf, :transparency], true)
clear_config([:mrf, :transparency_exclusions], ["other.site"])
option = Config.get([:instance, :mrf_transparency])
Config.put([:instance, :mrf_transparency], true)
exclusions = Config.get([:instance, :mrf_transparency_exclusions])
Config.put([:instance, :mrf_transparency_exclusions], ["other.site"])
simple_config = %{"reject" => ["example.com", "other.site"]} simple_config = %{"reject" => ["example.com", "other.site"]}
expected_config = %{"reject" => ["example.com"]} clear_config(:mrf_simple, simple_config)
Config.put(:mrf_simple, simple_config) expected_config = %{"reject" => ["example.com"]}
response = response =
conn conn
@ -199,10 +184,5 @@ test "it performs exclusions from MRF transparency data if configured", %{conn:
assert response["metadata"]["federation"]["mrf_simple"] == expected_config assert response["metadata"]["federation"]["mrf_simple"] == expected_config
assert response["metadata"]["federation"]["exclusions"] == true assert response["metadata"]["federation"]["exclusions"] == true
Config.put([:instance, :rewrite_policy], config)
Config.put([:instance, :mrf_transparency], option)
Config.put([:instance, :mrf_transparency_exclusions], exclusions)
Config.put(:mrf_simple, %{})
end end
end end

View file

@ -13,7 +13,6 @@ defmodule Pleroma.Workers.Cron.PurgeExpiredActivitiesWorkerTest do
setup do setup do
clear_config([ActivityExpiration, :enabled]) clear_config([ActivityExpiration, :enabled])
clear_config([:instance, :rewrite_policy])
end end
test "deletes an expiration activity" do test "deletes an expiration activity" do
@ -42,10 +41,7 @@ test "deletes an expiration activity" do
test "works with ActivityExpirationPolicy" do test "works with ActivityExpirationPolicy" do
Pleroma.Config.put([ActivityExpiration, :enabled], true) Pleroma.Config.put([ActivityExpiration, :enabled], true)
Pleroma.Config.put( clear_config([:mrf, :policies], Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy)
[:instance, :rewrite_policy],
Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy
)
user = insert(:user) user = insert(:user)