Merge branch 'deletions' into 'develop'

Deletions

See merge request !26
This commit is contained in:
lambadalambda 2017-09-04 14:49:55 -04:00
commit ea57e42b25
11 changed files with 134 additions and 7 deletions

View file

@ -75,6 +75,23 @@ def unfollow(follower, followed, local \\ true) do
end
end
def delete(%Object{data: %{"id" => id, "actor" => actor}} = object, local \\ true) do
user = User.get_cached_by_ap_id(actor)
data = %{
"type" => "Delete",
"actor" => actor,
"object" => id,
"to" => [user.follower_address, "https://www.w3.org/ns/activitystreams#Public"]
}
with Repo.delete(object),
Repo.delete_all(Activity.all_non_create_by_object_ap_id_q(id)),
Repo.delete_all(Activity.all_by_object_ap_id_q(id)),
{:ok, activity} <- insert(data, local),
:ok <- maybe_federate(activity) do
{:ok, activity}
end
end
def fetch_activities_for_context(context) do
query = from activity in Activity,
where: fragment("? @> ?", activity.data, ^%{ type: "Create", context: context }),

View file

@ -199,6 +199,25 @@ def to_simple_form(%{data: %{"type" => "Undo"}} = activity, user, with_author) d
] ++ mentions ++ author
end
def to_simple_form(%{data: %{"type" => "Delete"}} = activity, user, with_author) do
h = fn(str) -> [to_charlist(str)] end
updated_at = activity.data["published"]
inserted_at = activity.data["published"]
author = if with_author, do: [{:author, UserRepresenter.to_simple_form(user)}], else: []
[
{:"activity:object-type", ['http://activitystrea.ms/schema/1.0/activity']},
{:"activity:verb", ['http://activitystrea.ms/schema/1.0/delete']},
{:id, h.(activity.data["object"])},
{:title, ['An object was deleted']},
{:content, [type: 'html'], ['An object was deleted']},
{:published, h.(inserted_at)},
{:updated, h.(updated_at)}
] ++ author
end
def wrap_with_entry(simple_form) do
[{
:entry, [

View file

@ -2,14 +2,13 @@ defmodule Pleroma.Web.OStatus.DeleteHandler do
require Logger
alias Pleroma.Web.{XML, OStatus}
alias Pleroma.{Activity, Object, Repo}
alias Pleroma.Web.ActivityPub.ActivityPub
def handle_delete(entry, doc \\ nil) do
with id <- XML.string_from_xpath("//id", entry),
object when not is_nil(object) <- Object.get_by_ap_id(id) do
Repo.delete(object)
Repo.delete_all(Activity.all_non_create_by_object_ap_id_q(id))
Repo.delete_all(Activity.all_by_object_ap_id_q(id))
nil
object when not is_nil(object) <- Object.get_by_ap_id(id),
{:ok, delete} <- ActivityPub.delete(object, false) do
delete
end
end
end

View file

@ -82,6 +82,7 @@ def user_fetcher(username) do
post "/statuses/update", TwitterAPI.Controller, :status_update
post "/statuses/retweet/:id", TwitterAPI.Controller, :retweet
post "/statuses/destroy/:id", TwitterAPI.Controller, :delete_post
post "/friendships/create", TwitterAPI.Controller, :follow
post "/friendships/destroy", TwitterAPI.Controller, :unfollow

View file

@ -96,6 +96,25 @@ def to_map(%Activity{data: %{"type" => "Undo", "published" => created_at, "objec
}
end
def to_map(%Activity{data: %{"type" => "Delete", "published" => created_at, "object" => deleted_object }} = activity, %{user: user} = opts) do
created_at = created_at |> Utils.date_to_asctime
%{
"id" => activity.id,
"uri" => activity.data["object"],
"user" => UserView.render("show.json", %{user: user, for: opts[:for]}),
"attentions" => [],
"statusnet_html" => "deleted notice {{tag",
"text" => "deleted notice {{tag" ,
"is_local" => activity.local,
"is_post_verb" => false,
"created_at" => created_at,
"in_reply_to_status_id" => nil,
"external_url" => activity.data["id"],
"activity_type" => "delete"
}
end
def to_map(%Activity{data: %{"object" => %{"content" => content} = object}} = activity, %{user: user} = opts) do
created_at = object["published"] |> Utils.date_to_asctime
like_count = object["like_count"] || 0
@ -117,6 +136,7 @@ def to_map(%Activity{data: %{"object" => %{"content" => content} = object}} = ac
%{
"id" => activity.id,
"uri" => activity.data["object"]["id"],
"user" => UserView.render("show.json", %{user: user, for: opts[:for]}),
"statusnet_html" => HtmlSanitizeEx.basic_html(content) |> Formatter.finmojifiy,
"text" => HtmlSanitizeEx.strip_tags(content),

View file

@ -265,6 +265,12 @@ defp activity_to_status(%Activity{data: %{"type" => "Announce"}} = activity, opt
ActivityRepresenter.to_map(activity, Map.merge(opts, %{users: [user, announced_actor], announced_activity: announced_activity}))
end
defp activity_to_status(%Activity{data: %{"type" => "Delete"}} = activity, opts) do
actor = get_in(activity.data, ["actor"])
user = User.get_cached_by_ap_id(actor)
ActivityRepresenter.to_map(activity, Map.merge(opts, %{user: user}))
end
defp activity_to_status(activity, opts) do
actor = get_in(activity.data, ["actor"])
user = User.get_cached_by_ap_id(actor)

View file

@ -2,7 +2,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
use Pleroma.Web, :controller
alias Pleroma.Web.TwitterAPI.{TwitterAPI, UserView}
alias Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter
alias Pleroma.{Repo, Activity, User}
alias Pleroma.{Repo, Activity, User, Object}
alias Pleroma.Web.ActivityPub.ActivityPub
alias Ecto.Changeset
@ -94,6 +94,17 @@ def follow(%{assigns: %{user: user}} = conn, params) do
end
end
def delete_post(%{assigns: %{user: user}} = conn, %{"id" => id}) do
with %Activity{data: %{"object" => %{"id" => object_id}}} <- Repo.get(Activity, id),
%Object{} = object <- Object.get_by_ap_id(object_id),
true <- user.ap_id == object.data["actor"],
{:ok, delete} <- ActivityPub.delete(object) |> IO.inspect do
json = ActivityRepresenter.to_json(delete, %{user: user, for: user})
conn
|> json_reply(200, json)
end
end
def unfollow(%{assigns: %{user: user}} = conn, params) do
case TwitterAPI.unfollow(user, params) do
{:ok, user, unfollowed} ->

File diff suppressed because one or more lines are too long

View file

@ -225,6 +225,29 @@ test "an unfollow activity" do
assert clean(res) == clean(expected)
end
test "a delete" do
user = insert(:user)
activity = %Activity{data: %{ "id" => "ap_id", "type" => "Delete", "actor" => user.ap_id, "object" => "some_id", "published" => "2017-06-18T12:00:18+00:00" }}
tuple = ActivityRepresenter.to_simple_form(activity, nil)
refute is_nil(tuple)
res = :xmerl.export_simple_content(tuple, :xmerl_xml) |> IO.iodata_to_binary
expected = """
<activity:object-type>http://activitystrea.ms/schema/1.0/activity</activity:object-type>
<activity:verb>http://activitystrea.ms/schema/1.0/delete</activity:verb>
<id>#{activity.data["object"]}</id>
<title>An object was deleted</title>
<content type="html">An object was deleted</content>
<published>#{activity.data["published"]}</published>
<updated>#{activity.data["published"]}</updated>
"""
assert clean(res) == clean(expected)
end
test "an unknown activity" do
tuple = ActivityRepresenter.to_simple_form(%Activity{}, nil)
assert is_nil(tuple)

View file

@ -16,13 +16,15 @@ test "it removes the mentioned activity" do
incoming = File.read!("test/fixtures/delete.xml")
|> String.replace("tag:mastodon.sdf.org,2017-06-10:objectId=310513:objectType=Status", note.data["object"]["id"])
{:ok, []} = OStatus.handle_incoming(incoming)
{:ok, [delete]} = OStatus.handle_incoming(incoming)
refute Repo.get(Activity, note.id)
refute Repo.get(Activity, like.id)
refute Object.get_by_ap_id(note.data["object"]["id"])
assert Repo.get(Activity, second_note.id)
assert Object.get_by_ap_id(second_note.data["object"]["id"])
assert delete.data["type"] == "Delete"
end
end
end

View file

@ -148,4 +148,17 @@ test "an undo for a follow" do
assert map["is_post_verb"] == false
assert map["activity_type"] == "undo"
end
test "a delete activity" do
object = insert(:note)
user = User.get_by_ap_id(object.data["actor"])
{:ok, delete} = ActivityPub.delete(object)
map = ActivityRepresenter.to_map(delete, %{user: user})
assert map["is_post_verb"] == false
assert map["activity_type"] == "delete"
assert map["id"] == object.data["id"]
end
end