Fix unfollows
[akkoma] / lib / pleroma / web / activity_pub / activity_pub.ex
index bb54c885cce42d331bb58dc09bd6466db5d18fe2..c2d540db97187d29503961f8885dc2cfa51a0ca6 100644 (file)
@@ -16,9 +16,23 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     (data["to"] || []) ++ (data["cc"] || [])
   end
 
+  defp check_actor_is_active(actor) do
+    if not is_nil(actor) do
+      with user <- User.get_cached_by_ap_id(actor),
+           nil <- user.info["deactivated"] do
+        :ok
+      else
+        _e -> :reject
+      end
+    else
+      :ok
+    end
+  end
+
   def insert(map, local \\ true) when is_map(map) do
     with nil <- Activity.get_by_ap_id(map["id"]),
          map <- lazy_put_activity_defaults(map),
+         :ok <- check_actor_is_active(map["actor"]),
          {:ok, map} <- MRF.filter(map),
          :ok <- insert_full_object(map) do
       {:ok, activity} =
@@ -117,11 +131,19 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     end
   end
 
-  def unlike(%User{} = actor, %Object{} = object) do
-    with %Activity{} = activity <- get_existing_like(actor.ap_id, object),
-         {:ok, _activity} <- Repo.delete(activity),
-         {:ok, object} <- remove_like_from_object(activity, object) do
-      {:ok, object}
+  def unlike(
+        %User{} = actor,
+        %Object{} = object,
+        activity_id \\ nil,
+        local \\ true
+      ) do
+    with %Activity{} = like_activity <- get_existing_like(actor.ap_id, object),
+         unlike_data <- make_unlike_data(actor, like_activity, activity_id),
+         {:ok, unlike_activity} <- insert(unlike_data, local),
+         {:ok, _activity} <- Repo.delete(like_activity),
+         {:ok, object} <- remove_like_from_object(like_activity, object),
+         :ok <- maybe_federate(unlike_activity) do
+      {:ok, unlike_activity, like_activity, object}
     else
       _e -> {:ok, object}
     end
@@ -170,12 +192,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     end
   end
 
-  def unfollow(follower, followed, local \\ true) do
+  def unfollow(follower, followed, activity_id \\ nil, local \\ true) do
     with %Activity{} = follow_activity <- fetch_latest_follow(follower, followed),
-         unfollow_data <- make_unfollow_data(follower, followed, follow_activity),
+         unfollow_data <- make_unfollow_data(follower, followed, follow_activity, activity_id),
          {:ok, activity} <- insert(unfollow_data, local),
-         :ok,
-         maybe_federate(activity) do
+         :ok <- maybe_federate(activity) do
       {:ok, activity}
     end
   end
@@ -199,6 +220,29 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     end
   end
 
+  def block(blocker, blocked, activity_id \\ nil, local \\ true) do
+    follow_activity = fetch_latest_follow(blocker, blocked)
+
+    if follow_activity do
+      unfollow(blocker, blocked, local)
+    end
+
+    with block_data <- make_block_data(blocker, blocked, activity_id),
+         {:ok, activity} <- insert(block_data, local),
+         :ok <- maybe_federate(activity) do
+      {:ok, activity}
+    end
+  end
+
+  def unblock(blocker, blocked, activity_id \\ nil, local \\ true) do
+    with %Activity{} = block_activity <- fetch_latest_block(blocker, blocked),
+         unblock_data <- make_unblock_data(blocker, blocked, block_activity, activity_id),
+         {:ok, activity} <- insert(unblock_data, local),
+         :ok <- maybe_federate(activity) do
+      {:ok, activity}
+    end
+  end
+
   def fetch_activities_for_context(context, opts \\ %{}) do
     public = ["https://www.w3.org/ns/activitystreams#Public"]
 
@@ -238,6 +282,25 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     |> Enum.reverse()
   end
 
+  def fetch_user_activities(user, reading_user, params \\ %{}) do
+    params =
+      params
+      |> Map.put("type", ["Create", "Announce"])
+      |> Map.put("actor_id", user.ap_id)
+      |> Map.put("whole_db", true)
+
+    recipients =
+      if reading_user do
+        ["https://www.w3.org/ns/activitystreams#Public"] ++
+          [reading_user.ap_id | reading_user.following]
+      else
+        ["https://www.w3.org/ns/activitystreams#Public"]
+      end
+
+    fetch_activities(recipients, params)
+    |> Enum.reverse()
+  end
+
   defp restrict_since(query, %{"since_id" => since_id}) do
     from(activity in query, where: activity.id > ^since_id)
   end
@@ -345,7 +408,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
       activity in query,
       where:
         fragment(
-          "(?->'to' \\?| ?)",
+          "not (coalesce(?->'cc', '{}'::jsonb) \\?| ?)",
           activity.data,
           ^["https://www.w3.org/ns/activitystreams#Public"]
         )
@@ -401,6 +464,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
           "url" => [%{"href" => data["image"]["url"]}]
         }
 
+    data = Transmogrifier.maybe_fix_user_object(data)
+
     user_data = %{
       ap_id: data["id"],
       info: %{