Create tombstone instead of object deletion See merge request pleroma/pleroma!593tags/v0.9.9
@@ -80,9 +80,8 @@ defmodule Pleroma.Notification do | |||||
end | end | ||||
def clear(user) do | def clear(user) do | ||||
query = from(n in Notification, where: n.user_id == ^user.id) | |||||
Repo.delete_all(query) | |||||
from(n in Notification, where: n.user_id == ^user.id) | |||||
|> Repo.delete_all() | |||||
end | end | ||||
def dismiss(%{id: user_id} = _user, id) do | def dismiss(%{id: user_id} = _user, id) do | ||||
@@ -4,7 +4,7 @@ | |||||
defmodule Pleroma.Object do | defmodule Pleroma.Object do | ||||
use Ecto.Schema | use Ecto.Schema | ||||
alias Pleroma.{Repo, Object, User, Activity} | |||||
alias Pleroma.{Repo, Object, User, Activity, ObjectTombstone} | |||||
import Ecto.{Query, Changeset} | import Ecto.{Query, Changeset} | ||||
schema "objects" do | schema "objects" do | ||||
@@ -66,8 +66,25 @@ defmodule Pleroma.Object do | |||||
Object.change(%Object{}, %{data: %{"id" => context}}) | Object.change(%Object{}, %{data: %{"id" => context}}) | ||||
end | end | ||||
def make_tombstone(%Object{data: %{"id" => id, "type" => type}}, deleted \\ DateTime.utc_now()) do | |||||
%ObjectTombstone{ | |||||
id: id, | |||||
formerType: type, | |||||
deleted: deleted | |||||
} | |||||
|> Map.from_struct() | |||||
end | |||||
def swap_object_with_tombstone(object) do | |||||
tombstone = make_tombstone(object) | |||||
object | |||||
|> Object.change(%{data: tombstone}) | |||||
|> Repo.update() | |||||
end | |||||
def delete(%Object{data: %{"id" => id}} = object) do | def delete(%Object{data: %{"id" => id}} = object) do | ||||
with Repo.delete(object), | |||||
with {:ok, _obj} = swap_object_with_tombstone(object), | |||||
Repo.delete_all(Activity.all_non_create_by_object_ap_id_q(id)), | Repo.delete_all(Activity.all_non_create_by_object_ap_id_q(id)), | ||||
{:ok, true} <- Cachex.del(:object_cache, "object:#{id}") do | {:ok, true} <- Cachex.del(:object_cache, "object:#{id}") do | ||||
{:ok, object} | {:ok, object} | ||||
@@ -0,0 +1,4 @@ | |||||
defmodule Pleroma.ObjectTombstone do | |||||
@enforce_keys [:id, :formerType, :deleted] | |||||
defstruct [:id, :formerType, :deleted, type: "Tombstone"] | |||||
end |
@@ -4,18 +4,19 @@ | |||||
defmodule Pleroma.ActivityTest do | defmodule Pleroma.ActivityTest do | ||||
use Pleroma.DataCase | use Pleroma.DataCase | ||||
alias Pleroma.Activity | |||||
import Pleroma.Factory | import Pleroma.Factory | ||||
test "returns an activity by it's AP id" do | test "returns an activity by it's AP id" do | ||||
activity = insert(:note_activity) | activity = insert(:note_activity) | ||||
found_activity = Pleroma.Activity.get_by_ap_id(activity.data["id"]) | |||||
found_activity = Activity.get_by_ap_id(activity.data["id"]) | |||||
assert activity == found_activity | assert activity == found_activity | ||||
end | end | ||||
test "returns activities by it's objects AP ids" do | test "returns activities by it's objects AP ids" do | ||||
activity = insert(:note_activity) | activity = insert(:note_activity) | ||||
[found_activity] = Pleroma.Activity.all_by_object_ap_id(activity.data["object"]["id"]) | |||||
[found_activity] = Activity.all_by_object_ap_id(activity.data["object"]["id"]) | |||||
assert activity == found_activity | assert activity == found_activity | ||||
end | end | ||||
@@ -23,8 +24,7 @@ defmodule Pleroma.ActivityTest do | |||||
test "returns the activity that created an object" do | test "returns the activity that created an object" do | ||||
activity = insert(:note_activity) | activity = insert(:note_activity) | ||||
found_activity = | |||||
Pleroma.Activity.get_create_activity_by_object_ap_id(activity.data["object"]["id"]) | |||||
found_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"]["id"]) | |||||
assert activity == found_activity | assert activity == found_activity | ||||
end | end | ||||
@@ -36,6 +36,8 @@ defmodule Pleroma.ObjectTest do | |||||
found_object = Object.get_by_ap_id(object.data["id"]) | found_object = Object.get_by_ap_id(object.data["id"]) | ||||
refute object == found_object | refute object == found_object | ||||
assert found_object.data["type"] == "Tombstone" | |||||
end | end | ||||
test "ensures cache is cleared for the object" do | test "ensures cache is cleared for the object" do | ||||
@@ -51,6 +53,8 @@ defmodule Pleroma.ObjectTest do | |||||
cached_object = Object.get_cached_by_ap_id(object.data["id"]) | cached_object = Object.get_cached_by_ap_id(object.data["id"]) | ||||
refute object == cached_object | refute object == cached_object | ||||
assert cached_object.data["type"] == "Tombstone" | |||||
end | end | ||||
end | end | ||||
end | end |
@@ -492,7 +492,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do | |||||
assert Repo.get(Activity, delete.id) != nil | assert Repo.get(Activity, delete.id) != nil | ||||
assert Repo.get(Object, object.id) == nil | |||||
assert Repo.get(Object, object.id).data["type"] == "Tombstone" | |||||
end | end | ||||
end | end | ||||
@@ -296,7 +296,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do | |||||
assert %{} = json_response(conn, 200) | assert %{} = json_response(conn, 200) | ||||
assert Repo.get(Activity, activity.id) == nil | |||||
refute Repo.get(Activity, activity.id) | |||||
end | end | ||||
test "when you didn't create it", %{conn: conn} do | test "when you didn't create it", %{conn: conn} do | ||||
@@ -25,7 +25,7 @@ defmodule Pleroma.Web.OStatus.DeleteHandlingTest do | |||||
refute Repo.get(Activity, note.id) | refute Repo.get(Activity, note.id) | ||||
refute Repo.get(Activity, like.id) | refute Repo.get(Activity, like.id) | ||||
refute Object.get_by_ap_id(note.data["object"]["id"]) | |||||
assert Object.get_by_ap_id(note.data["object"]["id"]).data["type"] == "Tombstone" | |||||
assert Repo.get(Activity, second_note.id) | assert Repo.get(Activity, second_note.id) | ||||
assert Object.get_by_ap_id(second_note.data["object"]["id"]) | assert Object.get_by_ap_id(second_note.data["object"]["id"]) | ||||
@@ -5,7 +5,7 @@ | |||||
defmodule Pleroma.Web.OStatus.OStatusControllerTest do | defmodule Pleroma.Web.OStatus.OStatusControllerTest do | ||||
use Pleroma.Web.ConnCase | use Pleroma.Web.ConnCase | ||||
import Pleroma.Factory | import Pleroma.Factory | ||||
alias Pleroma.{User, Repo} | |||||
alias Pleroma.{User, Repo, Object} | |||||
alias Pleroma.Web.CommonAPI | alias Pleroma.Web.CommonAPI | ||||
alias Pleroma.Web.OStatus.ActivityRepresenter | alias Pleroma.Web.OStatus.ActivityRepresenter | ||||
@@ -114,6 +114,22 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do | |||||
|> response(404) | |> response(404) | ||||
end | end | ||||
test "404s on deleted objects", %{conn: conn} do | |||||
note_activity = insert(:note_activity) | |||||
[_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["object"]["id"])) | |||||
object = Object.get_by_ap_id(note_activity.data["object"]["id"]) | |||||
conn | |||||
|> get("/objects/#{uuid}") | |||||
|> response(200) | |||||
Object.delete(object) | |||||
conn | |||||
|> get("/objects/#{uuid}") | |||||
|> response(404) | |||||
end | |||||
test "gets an activity", %{conn: conn} do | test "gets an activity", %{conn: conn} do | ||||
note_activity = insert(:note_activity) | note_activity = insert(:note_activity) | ||||
[_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"])) | [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"])) | ||||