config descriptions for custom MRF policies
authorAlexander Strizhakov <alex.strizhakov@gmail.com>
Tue, 10 Nov 2020 16:18:53 +0000 (19:18 +0300)
committerAlexander Strizhakov <alex.strizhakov@gmail.com>
Tue, 10 Nov 2020 16:20:14 +0000 (19:20 +0300)
16 files changed:
config/description.exs
lib/pleroma/docs/json.ex
lib/pleroma/web/activity_pub/mrf.ex
lib/pleroma/web/activity_pub/mrf/activity_expiration_policy.ex
lib/pleroma/web/activity_pub/mrf/hellthread_policy.ex
lib/pleroma/web/activity_pub/mrf/keyword_policy.ex
lib/pleroma/web/activity_pub/mrf/mention_policy.ex
lib/pleroma/web/activity_pub/mrf/normalize_markup.ex
lib/pleroma/web/activity_pub/mrf/object_age_policy.ex
lib/pleroma/web/activity_pub/mrf/reject_non_public.ex
lib/pleroma/web/activity_pub/mrf/simple_policy.ex
lib/pleroma/web/activity_pub/mrf/subchain_policy.ex
lib/pleroma/web/activity_pub/mrf/user_allow_list_policy.ex
lib/pleroma/web/activity_pub/mrf/vocabulary_policy.ex
test/fixtures/modules/good_mrf.ex [new file with mode: 0644]
test/pleroma/web/activity_pub/mrf_test.exs

index 0b651696b4bb37fa0a76fef692606c3adefd07a5..69072312c840bb9e5ee1b9d973c5587f325408f1 100644 (file)
@@ -1,5 +1,4 @@
 use Mix.Config
-alias Pleroma.Docs.Generator
 
 websocket_config = [
   path: "/websocket",
@@ -1589,264 +1588,6 @@ config :pleroma, :config_description, [
       }
     ]
   },
-  %{
-    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,
     key: :media_proxy,
@@ -3159,22 +2900,6 @@ config :pleroma, :config_description, [
       }
     ]
   },
-  %{
-    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,
     key: Pleroma.User,
@@ -3364,33 +3089,6 @@ config :pleroma, :config_description, [
       }
     ]
   },
-  %{
-    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,
     key: :modules,
index 13618b509430a72f839069e142bd269ecb03f9c4..a583e2a5b7d31daa8734f2ff1896d7254a8de02c 100644 (file)
@@ -11,7 +11,11 @@ defmodule Pleroma.Docs.JSON do
 
   @spec compile :: :ok
   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
 
   @spec compiled_descriptions :: Map.t()
index 5e5361082755d11f3036d678d0f6881564b15433..656e4c7ca1cf3373b20cff146e66398adef7f30c 100644 (file)
@@ -3,7 +3,26 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.MRF do
+  require Logger
+
+  @default_description %{
+    label: "",
+    description: "",
+    children: []
+  }
+
+  @required_description_keys [:key, :related_policy]
+
   @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
     policies
@@ -51,8 +70,6 @@ defmodule Pleroma.Web.ActivityPub.MRF do
     Enum.any?(domains, fn domain -> Regex.match?(domain, host) end)
   end
 
-  @callback describe() :: {:ok | :error, Map.t()}
-
   def describe(policies) do
     {:ok, policy_configs} =
       policies
@@ -82,4 +99,41 @@ defmodule Pleroma.Web.ActivityPub.MRF do
   end
 
   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, [], 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
index bee47b4edd4b47e0931d1db953b6b2fd916f61ea..655a2ced06034927fd83d2f4bc7aafcbccffe90e 100644 (file)
@@ -40,4 +40,22 @@ defmodule Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy do
       _ -> Map.put(activity, "expires_at", expires_at)
     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
index 9ba07b4e38b73c4a1bffdfba131511aee90855f9..3fd5c1e0a9c5cf6a3dd19fb6ad89baad58d94d92 100644 (file)
@@ -97,4 +97,31 @@ defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicy do
   @impl true
   def describe,
     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
index db66cfa3ec92638e9f556c4cd90b401c313daeda..ded0fe7f277de1a4ddbddadb688b2d6f3bd75f69 100644 (file)
@@ -126,4 +126,46 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do
 
     {:ok, %{mrf_keyword: mrf_keyword}}
   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
index 7910ca131830d3b782a2f3d5040c13f2196caefd..9c096712a653abc71724e107e7e6c0eb9c4a68c8 100644 (file)
@@ -25,4 +25,22 @@ defmodule Pleroma.Web.ActivityPub.MRF.MentionPolicy do
 
   @impl true
   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
index 7abae37aea2486161dd49cc0203ede72b50338e1..e00575c2a3cefb1e7baf512a8224ad81b0c35ee1 100644 (file)
@@ -8,6 +8,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkup do
 
   @behaviour Pleroma.Web.ActivityPub.MRF
 
+  @impl true
   def filter(%{"type" => "Create", "object" => child_object} = object) do
     scrub_policy = Pleroma.Config.get([:mrf_normalize_markup, :scrub_policy])
 
@@ -22,5 +23,23 @@ defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkup do
 
   def filter(object), do: {:ok, object}
 
+  @impl true
   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
index d45d2d7e36ef2ce1644d569cf4fae60f0fb2c740..eb0481f20a2e3fbf32912f3302e925adea6c7c30 100644 (file)
@@ -106,4 +106,32 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy do
 
     {:ok, %{mrf_object_age: mrf_object_age}}
   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
index 0b9ed2224dc82a334f6a2efc7d4082a311651bd9..cd7665e313d87989cdc7049d7e82150cc2f71105 100644 (file)
@@ -48,4 +48,27 @@ defmodule Pleroma.Web.ActivityPub.MRF.RejectNonPublic do
   @impl true
   def describe,
     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
index 16117772717091489ae3c7b5fa0b76e651bad7ab..6cd91826db178ba72f9cc0859fe7eac5c7397eca 100644 (file)
@@ -244,4 +244,78 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
 
     {:ok, %{mrf_simple: mrf_simple}}
   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
index 048052da69fdd5097e2271e6b621fce7e0a38813..2ec45260ad76523df8660af4a935eab9b3d38946 100644 (file)
@@ -39,4 +39,28 @@ defmodule Pleroma.Web.ActivityPub.MRF.SubchainPolicy do
 
   @impl true
   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
index 1a28f2ba21d118563324d36b9e602d6d87eb60a9..885bcca6fb97e354cd3755063c781e4cc01bbf23 100644 (file)
@@ -41,4 +41,18 @@ defmodule Pleroma.Web.ActivityPub.MRF.UserAllowListPolicy do
 
     {:ok, %{mrf_user_allowlist: mrf_user_allowlist}}
   end
+
+  @impl true
+  def config_description do
+    %{
+      key: :mrf_user_allowlist,
+      related_policy: "Pleroma.Web.ActivityPub.MRF.UserAllowListPolicy",
+      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
index a6c5455702c27cdc733619e5ecc90a9f780962ca..f325cb680dca9e081aa19d036a73f321aef66a37 100644 (file)
@@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.VocabularyPolicy do
 
   @behaviour Pleroma.Web.ActivityPub.MRF
 
+  @impl true
   def filter(%{"type" => "Undo", "object" => child_message} = message) do
     with {:ok, _} <- filter(child_message) do
       {:ok, message}
@@ -36,6 +37,33 @@ defmodule Pleroma.Web.ActivityPub.MRF.VocabularyPolicy do
 
   def filter(message), do: {:ok, message}
 
+  @impl true
   def describe,
     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
diff --git a/test/fixtures/modules/good_mrf.ex b/test/fixtures/modules/good_mrf.ex
new file mode 100644 (file)
index 0000000..39d0f14
--- /dev/null
@@ -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
index e8cdde2e1f82a91c7f7bb6b8ed053b838da44f86..17aef2e16a042e79f97bab21fa12c6ed7caa2ec5 100644 (file)
@@ -87,4 +87,21 @@ defmodule Pleroma.Web.ActivityPub.MRFTest do
       {:ok, ^expected} = MRF.describe()
     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",
+             children: [],
+             group: :pleroma,
+             tab: :mrf,
+             type: :group
+           }
+  end
 end