pleroma/lib/pleroma/web/activity_pub/mrf/tag_policy.ex
ilja ab081932c7
Fix tagpolicy to also work with Update
Objects who got updated would just pass the TagPolicy, undoing the moderation that was set in place for the Actor.
Now we check not only for Create activities, but also Update activities.
2022-12-09 15:09:48 +01:00

164 lines
4.5 KiB
Elixir

# 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.TagPolicy do
alias Pleroma.User
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
@moduledoc """
Apply policies based on user tags
This policy applies policies on a user activities depending on their tags
on your instance.
- `mrf_tag:media-force-nsfw`: Mark as sensitive on presence of attachments
- `mrf_tag:media-strip`: Remove attachments
- `mrf_tag:force-unlisted`: Mark as unlisted (removes from the federated timeline)
- `mrf_tag:sandbox`: Remove from public (local and federated) timelines
- `mrf_tag:disable-remote-subscription`: Reject non-local follow requests
- `mrf_tag:disable-any-subscription`: Reject any follow requests
"""
require Pleroma.Constants
defp get_tags(%User{tags: tags}) when is_list(tags), do: tags
defp get_tags(_), do: []
defp process_tag(
"mrf_tag:media-force-nsfw",
%{
"type" => type,
"object" => %{"attachment" => child_attachment}
} = message
)
when length(child_attachment) > 0 and type in ["Create", "Update"] do
{:ok, Kernel.put_in(message, ["object", "sensitive"], true)}
end
defp process_tag(
"mrf_tag:media-strip",
%{
"type" => type,
"object" => %{"attachment" => child_attachment} = object
} = message
)
when length(child_attachment) > 0 and type in ["Create", "Update"] do
object = Map.delete(object, "attachment")
message = Map.put(message, "object", object)
{:ok, message}
end
defp process_tag(
"mrf_tag:force-unlisted",
%{
"type" => type,
"to" => to,
"cc" => cc,
"actor" => actor,
"object" => object
} = message
) when type in ["Create", "Update"] do
user = User.get_cached_by_ap_id(actor)
if Enum.member?(to, Pleroma.Constants.as_public()) do
to = List.delete(to, Pleroma.Constants.as_public()) ++ [user.follower_address]
cc = List.delete(cc, user.follower_address) ++ [Pleroma.Constants.as_public()]
object =
object
|> Map.put("to", to)
|> Map.put("cc", cc)
message =
message
|> Map.put("to", to)
|> Map.put("cc", cc)
|> Map.put("object", object)
{:ok, message}
else
{:ok, message}
end
end
defp process_tag(
"mrf_tag:sandbox",
%{
"type" => type,
"to" => to,
"cc" => cc,
"actor" => actor,
"object" => object
} = message
) when type in ["Create", "Update"] do
user = User.get_cached_by_ap_id(actor)
if Enum.member?(to, Pleroma.Constants.as_public()) or
Enum.member?(cc, Pleroma.Constants.as_public()) do
to = List.delete(to, Pleroma.Constants.as_public()) ++ [user.follower_address]
cc = List.delete(cc, Pleroma.Constants.as_public())
object =
object
|> Map.put("to", to)
|> Map.put("cc", cc)
message =
message
|> Map.put("to", to)
|> Map.put("cc", cc)
|> Map.put("object", object)
{:ok, message}
else
{:ok, message}
end
end
defp process_tag(
"mrf_tag:disable-remote-subscription",
%{"type" => "Follow", "actor" => actor} = message
) do
user = User.get_cached_by_ap_id(actor)
if user.local == true do
{:ok, message}
else
{:reject,
"[TagPolicy] Follow from #{actor} tagged with mrf_tag:disable-remote-subscription"}
end
end
defp process_tag("mrf_tag:disable-any-subscription", %{"type" => "Follow", "actor" => actor}),
do: {:reject, "[TagPolicy] Follow from #{actor} tagged with mrf_tag:disable-any-subscription"}
defp process_tag(_, message), do: {:ok, message}
def filter_message(actor, message) do
User.get_cached_by_ap_id(actor)
|> get_tags()
|> Enum.reduce({:ok, message}, fn
tag, {:ok, message} ->
process_tag(tag, message)
_, error ->
error
end)
end
@impl true
def filter(%{"object" => target_actor, "type" => "Follow"} = message),
do: filter_message(target_actor, message)
@impl true
def filter(%{"actor" => actor, "type" => type} = message) when type in ["Create", "Update"],
do: filter_message(actor, message)
@impl true
def filter(message), do: {:ok, message}
@impl true
def describe, do: {:ok, %{}}
end