moving mrf settings from instance to separate group
authorAlexander Strizhakov <alex.strizhakov@gmail.com>
Sat, 21 Mar 2020 06:47:05 +0000 (09:47 +0300)
committerAlexander Strizhakov <alex.strizhakov@gmail.com>
Tue, 16 Jun 2020 15:32:18 +0000 (18:32 +0300)
16 files changed:
CHANGELOG.md
config/config.exs
config/description.exs
docs/configuration/cheatsheet.md
docs/configuration/mrf.md
lib/pleroma/config/config_db.ex
lib/pleroma/config/deprecation_warnings.ex
lib/pleroma/web/activity_pub/mrf.ex
lib/pleroma/web/activity_pub/mrf/simple_policy.ex
lib/pleroma/web/mastodon_api/views/instance_view.ex
priv/repo/migrations/20200323122421_mrf_config_move_from_instance_namespace.exs [new file with mode: 0644]
test/config/deprecation_warnings_test.exs [new file with mode: 0644]
test/tasks/config_test.exs
test/web/activity_pub/mrf/mrf_test.exs
test/web/federator_test.exs
test/web/node_info_test.exs

index d2629bf842312bd8fa2d49a62a0fd7607b9c7a76..12e8d58e65368915623a9e88d23fd43ef7bd80a4 100644 (file)
@@ -4,10 +4,13 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 
 ## [unreleased]
-
 ### Changed
 - MFR policy to set global expiration for all local Create activities
 - OGP rich media parser merged with TwitterCard
+- Configuration: `rewrite_policy` renamed to `policies` and moved from `instance` to `mrf` group. Old config namespace is deprecated.
+- Configuration: `mrf_transparency` renamed to `transparency` and moved from `instance` to `mrf` group. Old config namespace is deprecated.
+- Configuration: `mrf_transparency_exclusions` renamed to `transparency_exclusions` and moved from `instance` to `mrf` group. Old config namespace is deprecated.
+
 <details>
   <summary>API Changes</summary>
 - **Breaking:** Emoji API: changed methods and renamed routes.
index 6a7bb9e063e18242ab50ac4aeb791f7bae63aead..3d6336a664f050089eee72bbaee74a4661a8ae49 100644 (file)
@@ -209,7 +209,6 @@ config :pleroma, :instance,
     Pleroma.Web.ActivityPub.Publisher
   ],
   allow_relay: true,
-  rewrite_policy: Pleroma.Web.ActivityPub.MRF.NoOpPolicy,
   public: true,
   quarantined_instances: [],
   managed_config: true,
@@ -220,8 +219,6 @@ config :pleroma, :instance,
     "text/markdown",
     "text/bbcode"
   ],
-  mrf_transparency: true,
-  mrf_transparency_exclusions: [],
   autofollowed_nicknames: [],
   max_pinned_statuses: 1,
   attachment_links: false,
@@ -685,6 +682,11 @@ config :pleroma, :restrict_unauthenticated,
 
 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
 # of this file so it overrides the configuration defined above.
 import_config "#{Mix.env()}.exs"
index b21d7840cb2c63dbc2ff2b5781410b434aa9dfa7..2ab95e5abd5d1955b3818e4b205abc5a8e5fbf67 100644 (file)
@@ -689,17 +689,6 @@ config :pleroma, :config_description, [
         type: :boolean,
         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,
         type: :boolean,
@@ -742,23 +731,6 @@ config :pleroma, :config_description, [
           "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,
         type: :boolean,
@@ -3325,5 +3297,41 @@ config :pleroma, :config_description, [
         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"
+        ]
+      }
+    ]
   }
 ]
index fad67fc4da1365765cba078caf1ad00a5512ff08..e9af604e2f84ef6ad982db5346d5d1373a76ba9d 100644 (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_reachability_timeout_days`: Timeout (in days) of each external federation target being unreachable prior to pausing federating to it.
 * `allow_relay`: Enable Pleroma’s 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`: Doesn’t modify activities (default).
-    * `Pleroma.Web.ActivityPub.MRF.DropPolicy`: Drops all activities. It generally doesn’t 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.
 * `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``.
 * `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
     older software for theses nicknames.
 * `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.
 * `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`: Doesn’t modify activities (default).
+    * `Pleroma.Web.ActivityPub.MRF.DropPolicy`: Drops all activities. It generally doesn’t 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
 ### MRF policies
 
 !!! 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
 * `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.
 
-* `timelines` - public and federated timelines
-  * `local` - public timeline
+* `timelines`: public and federated timelines
+  * `local`: public timeline
   * `federated`
-* `profiles` - user profiles
+* `profiles`: user profiles
   * `local`
   * `remote`
-* `activities` - statuses
+* `activities`: statuses
   * `local`
   * `remote`
 
index d48d0cc991abd89db3e99079ebed96fd46cd976f..31c66e098a33e14f05455474936424232f252910 100644 (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:
 
 ```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:
@@ -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`:
 
 ```elixir
-config :pleroma, :instance,
-  rewrite_policy: [Pleroma.Web.ActivityPub.MRF.SimplePolicy]
+config :pleroma, :mrf,
+  policies: [Pleroma.Web.ActivityPub.MRF.SimplePolicy]
 
 config :pleroma, :mrf_simple,
   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
 
-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":
 
@@ -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:
 
 ```elixir
-config :pleroma, :instance,
-  rewrite_policy: [
+config :pleroma, :mrf,
+  policies: [
     Pleroma.Web.ActivityPub.MRF.SimplePolicy,
     Pleroma.Web.ActivityPub.MRF.RewritePolicy
   ]
index 30bd51b05a2ab68ec70e2db8ee35b8bb15026215..c0f3fe888c2bcb767d05fc75cc0e12768df97897 100644 (file)
@@ -54,13 +54,13 @@ defmodule Pleroma.ConfigDB do
 
   defp create(params) do
     %ConfigDB{}
-    |> changeset(params)
+    |> changeset(params, transform?)
     |> Repo.insert()
   end
 
   defp update(%ConfigDB{} = config, %{value: value}) do
     config
-    |> changeset(%{value: value})
+    |> changeset(%{value: value}, transform?)
     |> Repo.update()
   end
 
@@ -167,7 +167,9 @@ defmodule Pleroma.ConfigDB do
     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
     search_opts = Map.delete(params, :subkeys)
 
index b68ded01f6bd486f575485515cd588c2e0b312e5..0a6c724fbd5090b8f36f6aabd4152869b6ca23e0 100644 (file)
@@ -3,9 +3,23 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Config.DeprecationWarnings do
+  alias Pleroma.Config
+
   require Logger
   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
     if Config.get([:mrf_hellthread, :threshold]) do
       Logger.warn("""
@@ -39,5 +53,35 @@ defmodule Pleroma.Config.DeprecationWarnings do
   def warn do
     check_hellthread_threshold()
     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
index 5a4a76085dd41e95016120e4c82fc21f607fc5a7..206d6af52baf91545916d3fbc4e7c546639f995e 100644 (file)
@@ -16,7 +16,7 @@ defmodule Pleroma.Web.ActivityPub.MRF do
   def filter(%{} = object), do: get_policies() |> filter(object)
 
   def get_policies do
-    Pleroma.Config.get([:instance, :rewrite_policy], []) |> get_policies()
+    Pleroma.Config.get([:mrf, :policies], []) |> get_policies()
   end
 
   defp get_policies(policy) when is_atom(policy), do: [policy]
@@ -51,7 +51,7 @@ defmodule Pleroma.Web.ActivityPub.MRF do
       get_policies()
       |> 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 =
       %{
index b7dcb1b861026622590103e1451f029fe75ecaf7..9cea6bcf9209868e7f6bf403a82d8c10c040f193 100644 (file)
@@ -3,21 +3,23 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
-  alias Pleroma.User
-  alias Pleroma.Web.ActivityPub.MRF
   @moduledoc "Filter activities depending on their origin instance"
   @behaviour Pleroma.Web.ActivityPub.MRF
 
+  alias Pleroma.Config
+  alias Pleroma.User
+  alias Pleroma.Web.ActivityPub.MRF
+
   require Pleroma.Constants
 
   defp check_accept(%{host: actor_host} = _actor_info, object) do
     accepts =
-      Pleroma.Config.get([:mrf_simple, :accept])
+      Config.get([:mrf_simple, :accept])
       |> MRF.subdomains_regex()
 
     cond do
       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}
       true -> {:reject, nil}
     end
@@ -25,7 +27,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
 
   defp check_reject(%{host: actor_host} = _actor_info, object) do
     rejects =
-      Pleroma.Config.get([:mrf_simple, :reject])
+      Config.get([:mrf_simple, :reject])
       |> MRF.subdomains_regex()
 
     if MRF.subdomain_match?(rejects, actor_host) do
@@ -41,7 +43,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
        )
        when length(child_attachment) > 0 do
     media_removal =
-      Pleroma.Config.get([:mrf_simple, :media_removal])
+      Config.get([:mrf_simple, :media_removal])
       |> MRF.subdomains_regex()
 
     object =
@@ -65,7 +67,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
          } = object
        ) do
     media_nsfw =
-      Pleroma.Config.get([:mrf_simple, :media_nsfw])
+      Config.get([:mrf_simple, :media_nsfw])
       |> MRF.subdomains_regex()
 
     object =
@@ -85,7 +87,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
 
   defp check_ftl_removal(%{host: actor_host} = _actor_info, object) do
     timeline_removal =
-      Pleroma.Config.get([:mrf_simple, :federated_timeline_removal])
+      Config.get([:mrf_simple, :federated_timeline_removal])
       |> MRF.subdomains_regex()
 
     object =
@@ -108,7 +110,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
 
   defp check_report_removal(%{host: actor_host} = _actor_info, %{"type" => "Flag"} = object) do
     report_removal =
-      Pleroma.Config.get([:mrf_simple, :report_removal])
+      Config.get([:mrf_simple, :report_removal])
       |> MRF.subdomains_regex()
 
     if MRF.subdomain_match?(report_removal, actor_host) do
@@ -122,7 +124,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
 
   defp check_avatar_removal(%{host: actor_host} = _actor_info, %{"icon" => _icon} = object) do
     avatar_removal =
-      Pleroma.Config.get([:mrf_simple, :avatar_removal])
+      Config.get([:mrf_simple, :avatar_removal])
       |> MRF.subdomains_regex()
 
     if MRF.subdomain_match?(avatar_removal, actor_host) do
@@ -136,7 +138,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
 
   defp check_banner_removal(%{host: actor_host} = _actor_info, %{"image" => _image} = object) do
     banner_removal =
-      Pleroma.Config.get([:mrf_simple, :banner_removal])
+      Config.get([:mrf_simple, :banner_removal])
       |> MRF.subdomains_regex()
 
     if MRF.subdomain_match?(banner_removal, actor_host) do
@@ -197,10 +199,10 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
 
   @impl true
   def describe do
-    exclusions = Pleroma.Config.get([:instance, :mrf_transparency_exclusions])
+    exclusions = Config.get([:mrf, :transparency_exclusions])
 
     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.into(%{})
 
index c498fe6326084e5302502a277fc29c145ba00d73..4f0ae4e8ffdaf4c8f401e9ec926e8a09b031f2af 100644 (file)
@@ -78,7 +78,7 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
   def federation do
     quarantined = Config.get([:instance, :quarantined_instances], [])
 
-    if Config.get([:instance, :mrf_transparency]) do
+    if Config.get([:mrf, :transparency]) do
       {:ok, data} = MRF.describe()
 
       data
diff --git a/priv/repo/migrations/20200323122421_mrf_config_move_from_instance_namespace.exs b/priv/repo/migrations/20200323122421_mrf_config_move_from_instance_namespace.exs
new file mode 100644 (file)
index 0000000..6f60946
--- /dev/null
@@ -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
diff --git a/test/config/deprecation_warnings_test.exs b/test/config/deprecation_warnings_test.exs
new file mode 100644 (file)
index 0000000..548ee87
--- /dev/null
@@ -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
index e1bddfebf42172572a4a5a9524d08f04860c4c44..bae1710745e76adfee71be975ef1b4d2709bc010 100644 (file)
@@ -120,14 +120,11 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
           federation_reachability_timeout_days: 7,
           federation_publisher_modules: [Pleroma.Web.ActivityPub.Publisher],
           allow_relay: true,
-          rewrite_policy: Pleroma.Web.ActivityPub.MRF.NoOpPolicy,
           public: true,
           quarantined_instances: [],
           managed_config: true,
           static_dir: "instance/static/",
           allowed_post_formats: ["text/plain", "text/html", "text/markdown", "text/bbcode"],
-          mrf_transparency: true,
-          mrf_transparency_exclusions: [],
           autofollowed_nicknames: [],
           max_pinned_statuses: 1,
           attachment_links: false,
@@ -174,7 +171,7 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
         end
 
       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
index c941066f2ead00d882846807a5816925e096d731..a63b254233fc2ecd9254c7adff3eb733488538b1 100644 (file)
@@ -60,8 +60,6 @@ defmodule Pleroma.Web.ActivityPub.MRFTest do
   end
 
   describe "describe/0" do
-    setup do: clear_config([:instance, :rewrite_policy])
-
     test "it works as expected with noop policy" do
       expected = %{
         mrf_policies: ["NoOpPolicy"],
@@ -72,7 +70,7 @@ defmodule Pleroma.Web.ActivityPub.MRFTest do
     end
 
     test "it works as expected with mock policy" do
-      Pleroma.Config.put([:instance, :rewrite_policy], [MRFModuleMock])
+      clear_config([:mrf, :policies], [MRFModuleMock])
 
       expected = %{
         mrf_policies: ["MRFModuleMock"],
index de90aa6e055af94b277cb8eded78a590c3104e47..592fdccd19168a86f3c42ff95f448a5c13df977a 100644 (file)
@@ -23,7 +23,7 @@ defmodule Pleroma.Web.FederatorTest do
 
   setup_all do: clear_config([:instance, :federating], true)
   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])
 
   describe "Publish an activity" do
@@ -158,7 +158,7 @@ defmodule Pleroma.Web.FederatorTest do
       Pleroma.Config.put([:mrf_keyword, :reject], ["lain"])
 
       Pleroma.Config.put(
-        [:instance, :rewrite_policy],
+        [:mrf, :policies],
         Pleroma.Web.ActivityPub.MRF.KeywordPolicy
       )
 
index 00925caad9b14344ca24b621059137118df2daff..06b33607fb4ace57cfe545e8976e6285a6c2aa8b 100644 (file)
@@ -67,10 +67,10 @@ defmodule Pleroma.Web.NodeInfoTest do
   end
 
   test "returns fieldsLimits field", %{conn: conn} do
-    Config.put([:instance, :max_account_fields], 10)
-    Config.put([:instance, :max_remote_account_fields], 15)
-    Config.put([:instance, :account_field_name_length], 255)
-    Config.put([:instance, :account_field_value_length], 2048)
+    clear_config([:instance, :max_account_fields], 10)
+    clear_config([:instance, :max_remote_account_fields], 15)
+    clear_config([:instance, :account_field_name_length], 255)
+    clear_config([:instance, :account_field_value_length], 2048)
 
     response =
       conn
@@ -84,8 +84,7 @@ defmodule Pleroma.Web.NodeInfoTest do
   end
 
   test "it returns the safe_dm_mentions feature if enabled", %{conn: conn} do
-    option = Config.get([:instance, :safe_dm_mentions])
-    Config.put([:instance, :safe_dm_mentions], true)
+    clear_config([:instance, :safe_dm_mentions], true)
 
     response =
       conn
@@ -102,8 +101,6 @@ defmodule Pleroma.Web.NodeInfoTest do
       |> json_response(:ok)
 
     refute "safe_dm_mentions" in response["metadata"]["features"]
-
-    Config.put([:instance, :safe_dm_mentions], option)
   end
 
   describe "`metadata/federation/enabled`" do
@@ -156,14 +153,11 @@ defmodule Pleroma.Web.NodeInfoTest do
   end
 
   test "it shows MRF transparency data if enabled", %{conn: conn} do
-    config = Config.get([:instance, :rewrite_policy])
-    Config.put([:instance, :rewrite_policy], [Pleroma.Web.ActivityPub.MRF.SimplePolicy])
-
-    option = Config.get([:instance, :mrf_transparency])
-    Config.put([:instance, :mrf_transparency], true)
+    clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.SimplePolicy])
+    clear_config([:mrf, :transparency], true)
 
     simple_config = %{"reject" => ["example.com"]}
-    Config.put(:mrf_simple, simple_config)
+    clear_config(:mrf_simple, simple_config)
 
     response =
       conn
@@ -171,26 +165,17 @@ defmodule Pleroma.Web.NodeInfoTest do
       |> json_response(:ok)
 
     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
 
   test "it performs exclusions from MRF transparency data if configured", %{conn: conn} do
-    config = Config.get([:instance, :rewrite_policy])
-    Config.put([:instance, :rewrite_policy], [Pleroma.Web.ActivityPub.MRF.SimplePolicy])
-
-    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"])
+    clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.SimplePolicy])
+    clear_config([:mrf, :transparency], true)
+    clear_config([:mrf, :transparency_exclusions], ["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 =
       conn
@@ -199,10 +184,5 @@ defmodule Pleroma.Web.NodeInfoTest do
 
     assert response["metadata"]["federation"]["mrf_simple"] == expected_config
     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