From 46aa8c18a211034bc102cfffec61c9cc8c3cdf02 Mon Sep 17 00:00:00 2001 From: rinpatch Date: Fri, 8 Feb 2019 12:38:24 +0300 Subject: [PATCH] Add keyword policy --- docs/config.md | 5 ++ .../web/activity_pub/mrf/keyword_policy.ex | 74 +++++++++++++++++++ .../web/nodeinfo/nodeinfo_controller.ex | 28 +++++++ 3 files changed, 107 insertions(+) create mode 100644 lib/pleroma/web/activity_pub/mrf/keyword_policy.ex diff --git a/docs/config.md b/docs/config.md index e042d216f..55d618925 100644 --- a/docs/config.md +++ b/docs/config.md @@ -151,6 +151,11 @@ This section is used to configure Pleroma-FE, unless ``:managed_config`` in ``:i * `delist_threshold`: Number of mentioned users after which the message gets delisted (the message can still be seen, but it will not show up in public timelines and mentioned users won't get notifications about it). Set to 0 to disable. * `reject_threshold`: Number of mentioned users after which the messaged gets rejected. Set to 0 to disable. +## :mrf_keyword +* `reject`: A list of patterns which result in message being rejected, each pattern can be a string or a [regular expression](https://hexdocs.pm/elixir/Regex.html) +* `ftl_removal`: A list of patterns which result in message being removed from federated timelines(a.k.a unlisted), each pattern can be a string or a [regular expression](https://hexdocs.pm/elixir/Regex.html) +* `replace`: A list of tuples containing `{pattern, replacement`, `pattern` can be a string or a [regular expression](https://hexdocs.pm/elixir/Regex.html) + ## :media_proxy * `enabled`: Enables proxying of remote media to the instance’s proxy * `base_url`: The base URL to access a user-uploaded file. Useful when you want to proxy the media files via another host/CDN fronts. diff --git a/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex b/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex new file mode 100644 index 000000000..6e2673e9c --- /dev/null +++ b/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex @@ -0,0 +1,74 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do + @behaviour Pleroma.Web.ActivityPub.MRF + defp string_matches?(string, pattern) when is_binary(pattern) do + String.contains?(string, pattern) + end + + defp string_matches?(string, pattern) do + String.match?(string, pattern) + end + + defp check_reject(%{"object" => %{"content" => content}} = message) do + if Enum.any?(Pleroma.Config.get([:mrf_keyword, :reject]), fn pattern -> + string_matches?(content, pattern) + end) do + {:reject, nil} + else + {:ok, message} + end + end + + defp check_ftl_removal(%{"to" => to, "object" => %{"content" => content}} = message) do + if "https://www.w3.org/ns/activitystreams#Public" in to and + Enum.any?(Pleroma.Config.get([:mrf_keyword, :ftl_removal]), fn pattern -> + string_matches?(content, pattern) + end) do + to = List.delete(to, "https://www.w3.org/ns/activitystreams#Public") + cc = ["https://www.w3.org/ns/activitystreams#Public" | [message["cc"] || []]] + + message = + message + |> Map.put("to", to) + |> Map.put("cc", cc) + + IO.inspect(message) + {:ok, message} + else + {:ok, message} + end + end + + defp check_replace(%{"object" => %{"content" => content}} = message) do + content = + Enum.reduce(Pleroma.Config.get([:mrf_keyword, :replace]), content, fn {pattern, replacement}, + acc -> + String.replace(acc, pattern, replacement) + end) + + {:ok, put_in(message["object"]["content"], content)} + end + + @impl true + def filter(%{"object" => %{"content" => nil}} = message) do + {:ok, message} + end + + @impl true + def filter(%{"type" => "Create", "object" => %{"content" => _content}} = message) do + with {:ok, message} <- check_reject(message), + {:ok, message} <- check_ftl_removal(message), + {:ok, message} <- check_replace(message) do + {:ok, message} + else + _e -> + {:reject, nil} + end + end + + @impl true + def filter(message), do: {:ok, message} +end diff --git a/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex b/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex index 21694a5ee..7c24d4761 100644 --- a/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex +++ b/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex @@ -44,6 +44,33 @@ defmodule Pleroma.Web.Nodeinfo.NodeinfoController do Application.get_env(:pleroma, :mrf_simple) |> Enum.into(%{}) + # This horror is needed to convert regex sigils to strings + mrf_keyword = + Application.get_env(:pleroma, :mrf_keyword) + |> Enum.map(fn {key, value} -> + {key, + Enum.map(value, fn + {pattern, replacement} -> + %{ + "pattern" => + if not is_binary(pattern) do + inspect(pattern) + else + pattern + end, + "replacement" => replacement + } + + pattern -> + if not is_binary(pattern) do + inspect(pattern) + else + pattern + end + end)} + end) + |> Enum.into(%{}) + mrf_policies = MRF.get_policies() |> Enum.map(fn policy -> to_string(policy) |> String.split(".") |> List.last() end) @@ -73,6 +100,7 @@ defmodule Pleroma.Web.Nodeinfo.NodeinfoController do %{ mrf_policies: mrf_policies, mrf_simple: mrf_simple, + mrf_keyword: mrf_keyword, mrf_user_allowlist: mrf_user_allowlist, quarantined_instances: quarantined }