parent
998437d4a4
commit
3bc7d12271
@ -0,0 +1,116 @@
|
||||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.HashtagPolicy do
|
||||
require Pleroma.Constants
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.Object
|
||||
|
||||
@moduledoc """
|
||||
Reject, TWKN-remove or Set-Sensitive messsages with specific hashtags (without the leading #)
|
||||
|
||||
Note: This MRF Policy is always enabled, if you want to disable it you have to set empty lists.
|
||||
"""
|
||||
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF
|
||||
|
||||
defp check_reject(message, hashtags) do
|
||||
if Enum.any?(Config.get([:mrf_hashtag, :reject]), fn match -> match in hashtags end) do
|
||||
{:reject, "[HashtagPolicy] Matches with rejected keyword"}
|
||||
else
|
||||
{:ok, message}
|
||||
end
|
||||
end
|
||||
|
||||
defp check_ftl_removal(%{"to" => to} = message, hashtags) do
|
||||
if Pleroma.Constants.as_public() in to and
|
||||
Enum.any?(Config.get([:mrf_hashtag, :federated_timeline_removal]), fn match ->
|
||||
match in hashtags
|
||||
end) do
|
||||
to = List.delete(to, Pleroma.Constants.as_public())
|
||||
cc = [Pleroma.Constants.as_public() | message["cc"] || []]
|
||||
|
||||
message =
|
||||
message
|
||||
|> Map.put("to", to)
|
||||
|> Map.put("cc", cc)
|
||||
|> Kernel.put_in(["object", "to"], to)
|
||||
|> Kernel.put_in(["object", "cc"], cc)
|
||||
|
||||
{:ok, message}
|
||||
else
|
||||
{:ok, message}
|
||||
end
|
||||
end
|
||||
|
||||
defp check_ftl_removal(message, _hashtags), do: {:ok, message}
|
||||
|
||||
defp check_sensitive(message, hashtags) do
|
||||
if Enum.any?(Config.get([:mrf_hashtag, :sensitive]), fn match -> match in hashtags end) do
|
||||
{:ok, Kernel.put_in(message, ["object", "sensitive"], true)}
|
||||
else
|
||||
{:ok, message}
|
||||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
def filter(%{"type" => "Create", "object" => object} = message) do
|
||||
hashtags = Object.hashtags(%Object{data: object})
|
||||
|
||||
if hashtags != [] do
|
||||
with {:ok, message} <- check_reject(message, hashtags),
|
||||
{:ok, message} <- check_ftl_removal(message, hashtags),
|
||||
{:ok, message} <- check_sensitive(message, hashtags) do
|
||||
{:ok, message}
|
||||
end
|
||||
else
|
||||
{:ok, message}
|
||||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
def filter(message), do: {:ok, message}
|
||||
|
||||
@impl true
|
||||
def describe do
|
||||
mrf_hashtag =
|
||||
Config.get(:mrf_hashtag)
|
||||
|> Enum.into(%{})
|
||||
|
||||
{:ok, %{mrf_hashtag: mrf_hashtag}}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def config_description do
|
||||
%{
|
||||
key: :mrf_hashtag,
|
||||
related_policy: "Pleroma.Web.ActivityPub.MRF.HashtagPolicy",
|
||||
label: "MRF Hashtag",
|
||||
description: @moduledoc,
|
||||
children: [
|
||||
%{
|
||||
key: :reject,
|
||||
type: {:list, :string},
|
||||
description: "A list of hashtags which result in message being rejected.",
|
||||
suggestions: ["foo"]
|
||||
},
|
||||
%{
|
||||
key: :federated_timeline_removal,
|
||||
type: {:list, :string},
|
||||
description:
|
||||
"A list of hashtags which result in message being removed from federated timelines (a.k.a unlisted).",
|
||||
suggestions: ["foo"]
|
||||
},
|
||||
%{
|
||||
key: :sensitive,
|
||||
type: {:list, :string},
|
||||
description:
|
||||
"A list of hashtags which result in message being set as sensitive (a.k.a NSFW/R-18)",
|
||||
suggestions: ["nsfw", "r18"]
|
||||
}
|
||||
]
|
||||
}
|
||||
end
|
||||
end
|
@ -0,0 +1,31 @@
|
||||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.HashtagPolicyTest do
|
||||
use Oban.Testing, repo: Pleroma.Repo
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
test "it sets the sensitive property with relevant hashtags" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "#nsfw hey"})
|
||||
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
|
||||
|
||||
assert modified["object"]["sensitive"]
|
||||
end
|
||||
|
||||
test "it doesn't sets the sensitive property with irrelevant hashtags" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "#cofe hey"})
|
||||
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
|
||||
|
||||
refute modified["object"]["sensitive"]
|
||||
end
|
||||
end
|
Loading…
Reference in new issue