Add ActivityExpirationPolicy
authorEgor Kislitsyn <egor@kislitsyn.com>
Tue, 11 Feb 2020 09:53:24 +0000 (13:53 +0400)
committerEgor Kislitsyn <egor@kislitsyn.com>
Thu, 13 Feb 2020 18:27:10 +0000 (22:27 +0400)
config/config.exs
lib/pleroma/web/activity_pub/mrf.ex
lib/pleroma/web/activity_pub/mrf/activity_expiration_policy.ex [new file with mode: 0644]
test/web/activity_pub/mrf/activity_expiration_policy_test.exs [new file with mode: 0644]

index 41c1ff6371a21e56af6a4fdaf45aaf79801096c1..d5b298c167d631b371ba7485994735129afd72e9 100644 (file)
@@ -361,6 +361,8 @@ config :pleroma, :mrf_keyword,
 
 config :pleroma, :mrf_subchain, match_actor: %{}
 
 
 config :pleroma, :mrf_subchain, match_actor: %{}
 
+config :pleroma, :mrf_activity_expiration, days: 365
+
 config :pleroma, :mrf_vocabulary,
   accept: [],
   reject: []
 config :pleroma, :mrf_vocabulary,
   accept: [],
   reject: []
index 263ed11af84a73a88c5539b98c19a4367faede43..b6e737de53dd6b18a4922c7ff394768dcec3287f 100644 (file)
@@ -8,11 +8,8 @@ defmodule Pleroma.Web.ActivityPub.MRF do
   def filter(policies, %{} = object) do
     policies
     |> Enum.reduce({:ok, object}, fn
   def filter(policies, %{} = object) do
     policies
     |> Enum.reduce({:ok, object}, fn
-      policy, {:ok, object} ->
-        policy.filter(object)
-
-      _, error ->
-        error
+      policy, {:ok, object} -> policy.filter(object)
+      _, error -> error
     end)
   end
 
     end)
   end
 
diff --git a/lib/pleroma/web/activity_pub/mrf/activity_expiration_policy.ex b/lib/pleroma/web/activity_pub/mrf/activity_expiration_policy.ex
new file mode 100644 (file)
index 0000000..1b88601
--- /dev/null
@@ -0,0 +1,35 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy do
+  @moduledoc "Adds expiration to all local activities"
+  @behaviour Pleroma.Web.ActivityPub.MRF
+
+  @impl true
+  def filter(%{"id" => id} = activity) do
+    activity =
+      if String.starts_with?(id, Pleroma.Web.Endpoint.url()) do
+        maybe_add_expiration(activity)
+      else
+        activity
+      end
+
+    {:ok, activity}
+  end
+
+  @impl true
+  def describe, do: {:ok, %{}}
+
+  defp maybe_add_expiration(activity) do
+    days = Pleroma.Config.get([:mrf_activity_expiration, :days], 365)
+    expires_at = NaiveDateTime.utc_now() |> Timex.shift(days: days)
+
+    with %{"expires_at" => existing_expires_at} <- activity,
+         :lt <- NaiveDateTime.compare(existing_expires_at, expires_at) do
+      activity
+    else
+      _ -> Map.put(activity, "expires_at", expires_at)
+    end
+  end
+end
diff --git a/test/web/activity_pub/mrf/activity_expiration_policy_test.exs b/test/web/activity_pub/mrf/activity_expiration_policy_test.exs
new file mode 100644 (file)
index 0000000..2e65048
--- /dev/null
@@ -0,0 +1,38 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicyTest do
+  use ExUnit.Case, async: true
+  alias Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy
+
+  @id Pleroma.Web.Endpoint.url() <> "/activities/cofe"
+
+  test "adds `expires_at` property" do
+    assert {:ok, %{"expires_at" => expires_at}} = ActivityExpirationPolicy.filter(%{"id" => @id})
+
+    assert Timex.diff(expires_at, NaiveDateTime.utc_now(), :days) == 364
+  end
+
+  test "keeps existing `expires_at` if it less than the config setting" do
+    expires_at = NaiveDateTime.utc_now() |> Timex.shift(days: 1)
+
+    assert {:ok, %{"expires_at" => ^expires_at}} =
+             ActivityExpirationPolicy.filter(%{"id" => @id, "expires_at" => expires_at})
+  end
+
+  test "owerwrites existing `expires_at` if it greater than the config setting" do
+    too_distant_future = NaiveDateTime.utc_now() |> Timex.shift(years: 2)
+
+    assert {:ok, %{"expires_at" => expires_at}} =
+             ActivityExpirationPolicy.filter(%{"id" => @id, "expires_at" => too_distant_future})
+
+    assert Timex.diff(expires_at, NaiveDateTime.utc_now(), :days) == 364
+  end
+
+  test "ignores remote activities" do
+    assert {:ok, activity} = ActivityExpirationPolicy.filter(%{"id" => "https://example.com/123"})
+
+    refute Map.has_key?(activity, "expires_at")
+  end
+end