From da2254089cbbdf5ac9cf705c75e9a5cc4014f872 Mon Sep 17 00:00:00 2001
From: Thomas Citharel <tcit@tcit.fr>
Date: Wed, 6 Apr 2022 15:49:42 +0200
Subject: [PATCH] Make sure suspended actors are not in the AP cache anymore

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
---
 lib/web/cache/activity_pub.ex                 | 10 ++++++++--
 .../activity_pub_controller_test.exs          | 19 +++++++++++++++++++
 test/web/controllers/page_controller_test.exs | 14 +++++++++++++-
 3 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/lib/web/cache/activity_pub.ex b/lib/web/cache/activity_pub.ex
index d19b70a0a..d00926075 100644
--- a/lib/web/cache/activity_pub.ex
+++ b/lib/web/cache/activity_pub.ex
@@ -29,9 +29,12 @@ defmodule Mobilizon.Web.Cache.ActivityPub do
   @spec do_get_actor(String.t()) :: {:commit, Actor.t()} | {:ignore, nil}
   defp do_get_actor("actor_" <> name) do
     case Actor.find_or_make_actor_from_nickname(name) do
-      {:ok, %ActorModel{} = actor} ->
+      {:ok, %ActorModel{suspended: false} = actor} ->
         {:commit, actor}
 
+      {:ok, %ActorModel{}} ->
+        {:ignore, nil}
+
       {:error, _err} ->
         {:ignore, nil}
     end
@@ -45,9 +48,12 @@ defmodule Mobilizon.Web.Cache.ActivityPub do
   def get_local_actor_by_name(name) do
     Cachex.fetch(@cache, "local_actor_" <> name, fn "local_actor_" <> name ->
       case Actors.get_local_actor_by_name(name) do
-        %ActorModel{} = actor ->
+        %ActorModel{suspended: false} = actor ->
           {:commit, actor}
 
+        {:ok, %ActorModel{}} ->
+          {:ignore, nil}
+
         nil ->
           {:ignore, nil}
       end
diff --git a/test/web/controllers/activity_pub_controller_test.exs b/test/web/controllers/activity_pub_controller_test.exs
index b9e59d605..95367865c 100644
--- a/test/web/controllers/activity_pub_controller_test.exs
+++ b/test/web/controllers/activity_pub_controller_test.exs
@@ -14,6 +14,7 @@ defmodule Mobilizon.Web.ActivityPubControllerTest do
   alias Mobilizon.Actors.Actor
 
   alias Mobilizon.Federation.ActivityPub
+  alias Mobilizon.Service.ActorSuspension
   alias Mobilizon.Service.HTTP.ActivityPub.Mock
   alias Mobilizon.Web.ActivityPub.ActorView
   alias Mobilizon.Web.{Endpoint, PageView}
@@ -44,6 +45,24 @@ defmodule Mobilizon.Web.ActivityPubControllerTest do
                |> Jason.encode!()
                |> Jason.decode!()
     end
+
+    test "it returns nothing if the actor is suspended", %{conn: conn} do
+      suspended = insert(:actor)
+
+      conn = get(conn, Actor.build_url(suspended.preferred_username, :page))
+      assert json_response(conn, 200)
+
+      assert {:ok, true} ==
+               Cachex.exists?(:activity_pub, "actor_" <> suspended.preferred_username)
+
+      ActorSuspension.suspend_actor(suspended)
+
+      assert {:ok, false} ==
+               Cachex.exists?(:activity_pub, "actor_" <> suspended.preferred_username)
+
+      conn = get(conn, Actor.build_url(suspended.preferred_username, :page))
+      assert json_response(conn, 404)
+    end
   end
 
   describe "/events/:uuid" do
diff --git a/test/web/controllers/page_controller_test.exs b/test/web/controllers/page_controller_test.exs
index ec41dee9c..651cdd13f 100644
--- a/test/web/controllers/page_controller_test.exs
+++ b/test/web/controllers/page_controller_test.exs
@@ -4,7 +4,7 @@ defmodule Mobilizon.Web.PageControllerTest do
   import Mobilizon.Factory
 
   alias Mobilizon.Actors.Actor
-
+  alias Mobilizon.Service.ActorSuspension
   alias Mobilizon.Web.Endpoint
   alias Mobilizon.Web.Router.Helpers, as: Routes
 
@@ -37,6 +37,18 @@ defmodule Mobilizon.Web.PageControllerTest do
       conn = get(conn, Actor.build_url("not_existing", :page))
       assert html_response(conn, 404)
     end
+
+    test "GET /@actor when suspended", %{conn: conn} do
+      suspended = insert(:actor)
+
+      conn = get(conn, Actor.build_url(suspended.preferred_username, :page))
+      assert html_response(conn, 200)
+
+      ActorSuspension.suspend_actor(suspended)
+
+      conn = get(conn, Actor.build_url(suspended.preferred_username, :page))
+      assert html_response(conn, 404)
+    end
   end
 
   test "GET /events/:uuid", %{conn: conn} do