Merge branch 'feature/create-tombstone-instead-of-delete' into 'develop'

Create tombstone instead of object deletion

See merge request pleroma/pleroma!593
This commit is contained in:
kaniini 2018-12-27 19:37:55 +00:00
commit bee6acd51d
9 changed files with 53 additions and 13 deletions

View file

@ -80,9 +80,8 @@ def get(%{id: user_id} = _user, id) do
end end
def clear(user) do def clear(user) do
query = from(n in Notification, where: n.user_id == ^user.id) from(n in Notification, where: n.user_id == ^user.id)
|> Repo.delete_all()
Repo.delete_all(query)
end end
def dismiss(%{id: user_id} = _user, id) do def dismiss(%{id: user_id} = _user, id) do

View file

@ -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 @@ def context_mapping(context) 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}

View file

@ -0,0 +1,4 @@
defmodule Pleroma.ObjectTombstone do
@enforce_keys [:id, :formerType, :deleted]
defstruct [:id, :formerType, :deleted, type: "Tombstone"]
end

View file

@ -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 @@ test "returns activities by it's objects AP ids" 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 = found_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"]["id"])
Pleroma.Activity.get_create_activity_by_object_ap_id(activity.data["object"]["id"])
assert activity == found_activity assert activity == found_activity
end end

View file

@ -36,6 +36,8 @@ test "deletes an object" 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 @@ test "ensures cache is cleared for the object" 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

View file

@ -492,7 +492,7 @@ test "it creates a delete activity and deletes the original object" 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

View file

@ -296,7 +296,7 @@ test "when you created it", %{conn: conn} 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

View file

@ -25,7 +25,7 @@ test "it removes the mentioned activity" 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"])

View file

@ -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 @@ test "404s on nonexisting objects", %{conn: conn} 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"]))