ab081932c7
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.
164 lines
4.5 KiB
Elixir
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
|