2019-11-14 18:48:10 -07:00
# Pleroma: A lightweight social networking server
2023-01-01 04:11:47 -07:00
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
2019-11-14 18:48:10 -07:00
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy do
alias Pleroma.Config
alias Pleroma.User
require Pleroma.Constants
@moduledoc " Filter activities depending on their age "
2021-06-07 13:22:08 -06:00
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
2019-11-14 18:48:10 -07:00
2020-04-20 06:59:16 -06:00
defp check_date ( %{ " object " = > %{ " published " = > published } } = message ) do
2019-11-14 18:48:10 -07:00
with % DateTime { } = now <- DateTime . utc_now ( ) ,
{ :ok , % DateTime { } = then , _ } <- DateTime . from_iso8601 ( published ) ,
max_ttl <- Config . get ( [ :mrf_object_age , :threshold ] ) ,
{ :ttl , false } <- { :ttl , DateTime . diff ( now , then ) > max_ttl } do
{ :ok , message }
else
{ :ttl , true } ->
{ :reject , nil }
e ->
{ :error , e }
end
end
defp check_reject ( message , actions ) do
if :reject in actions do
2020-07-13 07:47:13 -06:00
{ :reject , " [ObjectAgePolicy] " }
2019-11-14 18:48:10 -07:00
else
{ :ok , message }
end
end
defp check_delist ( message , actions ) do
if :delist in actions do
with % User { } = user <- User . get_cached_by_ap_id ( message [ " actor " ] ) do
2020-08-03 06:12:32 -06:00
to =
List . delete ( message [ " to " ] || [ ] , Pleroma.Constants . as_public ( ) ) ++
[ user . follower_address ]
cc =
List . delete ( message [ " cc " ] || [ ] , user . follower_address ) ++
[ Pleroma.Constants . as_public ( ) ]
2019-11-14 18:48:10 -07:00
message =
message
|> Map . put ( " to " , to )
|> Map . put ( " cc " , cc )
2021-08-09 23:41:06 -06:00
|> Kernel . put_in ( [ " object " , " to " ] , to )
|> Kernel . put_in ( [ " object " , " cc " ] , cc )
2019-11-14 18:48:10 -07:00
{ :ok , message }
else
2019-11-14 18:56:14 -07:00
_e ->
2020-07-13 07:47:13 -06:00
{ :reject , " [ObjectAgePolicy] Unhandled error " }
2019-11-14 18:48:10 -07:00
end
else
{ :ok , message }
end
end
defp check_strip_followers ( message , actions ) do
if :strip_followers in actions do
with % User { } = user <- User . get_cached_by_ap_id ( message [ " actor " ] ) do
2020-08-03 06:12:32 -06:00
to = List . delete ( message [ " to " ] || [ ] , user . follower_address )
cc = List . delete ( message [ " cc " ] || [ ] , user . follower_address )
2019-11-14 18:48:10 -07:00
message =
message
|> Map . put ( " to " , to )
|> Map . put ( " cc " , cc )
2021-08-09 23:41:06 -06:00
|> Kernel . put_in ( [ " object " , " to " ] , to )
|> Kernel . put_in ( [ " object " , " cc " ] , cc )
2019-11-14 18:48:10 -07:00
{ :ok , message }
else
_e ->
2020-07-13 07:47:13 -06:00
{ :reject , " [ObjectAgePolicy] Unhandled error " }
2019-11-14 18:48:10 -07:00
end
else
{ :ok , message }
end
end
@impl true
2021-08-09 23:41:06 -06:00
def filter ( %{ " type " = > " Create " , " object " = > %{ " published " = > _ } } = message ) do
2019-11-14 18:48:10 -07:00
with actions <- Config . get ( [ :mrf_object_age , :actions ] ) ,
{ :reject , _ } <- check_date ( message ) ,
{ :ok , message } <- check_reject ( message , actions ) ,
{ :ok , message } <- check_delist ( message , actions ) ,
{ :ok , message } <- check_strip_followers ( message , actions ) do
{ :ok , message }
else
# check_date() is allowed to short-circuit the pipeline
e -> e
end
end
@impl true
def filter ( message ) , do : { :ok , message }
@impl true
2020-04-20 06:59:16 -06:00
def describe do
mrf_object_age =
2020-07-09 09:53:51 -06:00
Config . get ( :mrf_object_age )
2020-04-20 06:59:16 -06:00
|> Enum . into ( %{ } )
{ :ok , %{ mrf_object_age : mrf_object_age } }
end
2020-11-10 09:18:53 -07:00
@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; " <>
2022-11-07 06:56:59 -07:00
" `:strip_followers` removes followers from the ActivityPub recipient list ensuring they won't be delivered to home timelines, additionally for followers-only it degrades to a direct message; " <>
2020-11-10 09:18:53 -07:00
" `:reject` rejects the message entirely " ,
suggestions : [ :delist , :strip_followers , :reject ]
}
]
}
end
2019-11-14 18:48:10 -07:00
end