summaryrefslogtreecommitdiff
path: root/lib/pleroma/web/activity_pub
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pleroma/web/activity_pub')
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex22
-rw-r--r--lib/pleroma/web/activity_pub/transmogrifier.ex71
-rw-r--r--lib/pleroma/web/activity_pub/utils.ex2
-rw-r--r--lib/pleroma/web/activity_pub/views/user_view.ex11
4 files changed, 72 insertions, 34 deletions
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index 195679fad..ec605b694 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -30,7 +30,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
def insert(map, local \\ true) when is_map(map) do
- with nil <- Activity.get_by_ap_id(map["id"]),
+ with nil <- Activity.normalize(map),
map <- lazy_put_activity_defaults(map),
:ok <- check_actor_is_active(map["actor"]),
{:ok, map} <- MRF.filter(map),
@@ -641,13 +641,23 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
Logger.info("Federating #{id} to #{inbox}")
host = URI.parse(inbox).host
+ digest = "SHA-256=" <> (:crypto.hash(:sha256, json) |> Base.encode64())
+
signature =
- Pleroma.Web.HTTPSignatures.sign(actor, %{host: host, "content-length": byte_size(json)})
+ Pleroma.Web.HTTPSignatures.sign(actor, %{
+ host: host,
+ "content-length": byte_size(json),
+ digest: digest
+ })
@httpoison.post(
inbox,
json,
- [{"Content-Type", "application/activity+json"}, {"signature", signature}],
+ [
+ {"Content-Type", "application/activity+json"},
+ {"signature", signature},
+ {"digest", digest}
+ ],
hackney: [pool: :default]
)
end
@@ -670,7 +680,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
recv_timeout: 20000
),
{:ok, data} <- Jason.decode(body),
- nil <- Object.get_by_ap_id(data["id"]),
+ nil <- Object.normalize(data),
params <- %{
"type" => "Create",
"to" => data["to"],
@@ -679,7 +689,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
"object" => data
},
{:ok, activity} <- Transmogrifier.handle_incoming(params) do
- {:ok, Object.get_by_ap_id(activity.data["object"]["id"])}
+ {:ok, Object.normalize(activity.data["object"])}
else
object = %Object{} ->
{:ok, object}
@@ -688,7 +698,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
Logger.info("Couldn't get object via AP, trying out OStatus fetching...")
case OStatus.fetch_activity_from_url(id) do
- {:ok, [activity | _]} -> {:ok, Object.get_by_ap_id(activity.data["object"]["id"])}
+ {:ok, [activity | _]} -> {:ok, Object.normalize(activity.data["object"])}
e -> e
end
end
diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index 30cd70fb6..e5fb6e033 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -13,18 +13,58 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
require Logger
+ def get_actor(%{"actor" => actor}) when is_binary(actor) do
+ actor
+ end
+
+ def get_actor(%{"actor" => actor}) when is_list(actor) do
+ Enum.at(actor, 0)
+ end
+
+ def get_actor(%{"actor" => actor}) when is_map(actor) do
+ actor["id"]
+ end
+
+ def get_actor(%{"actor" => actor_list}) do
+ Enum.find(actor_list, fn %{"type" => type} -> type == "Person" end)
+ |> Map.get("id")
+ end
+
@doc """
Modifies an incoming AP object (mastodon format) to our internal format.
"""
def fix_object(object) do
object
- |> Map.put("actor", object["attributedTo"])
+ |> fix_actor
|> fix_attachments
|> fix_context
|> fix_in_reply_to
|> fix_emoji
|> fix_tag
|> fix_content_map
+ |> fix_addressing
+ end
+
+ def fix_addressing_list(map, field) do
+ if is_binary(map[field]) do
+ map
+ |> Map.put(field, [map[field]])
+ else
+ map
+ end
+ end
+
+ def fix_addressing(map) do
+ map
+ |> fix_addressing_list("to")
+ |> fix_addressing_list("cc")
+ |> fix_addressing_list("bto")
+ |> fix_addressing_list("bcc")
+ end
+
+ def fix_actor(%{"attributedTo" => actor} = object) do
+ object
+ |> Map.put("actor", get_actor(%{"actor" => actor}))
end
def fix_in_reply_to(%{"inReplyTo" => in_reply_to_id} = object)
@@ -122,7 +162,14 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
# TODO: validate those with a Ecto scheme
# - tags
# - emoji
- def handle_incoming(%{"type" => "Create", "object" => %{"type" => "Note"} = object} = data) do
+ def handle_incoming(%{"type" => "Create", "object" => %{"type" => objtype} = object} = data)
+ when objtype in ["Article", "Note"] do
+ actor = get_actor(data)
+
+ data =
+ Map.put(data, "actor", actor)
+ |> fix_addressing
+
with nil <- Activity.get_create_activity_by_object_ap_id(object["id"]),
%User{} = user <- User.get_or_fetch_by_ap_id(data["actor"]) do
object = fix_object(data["object"])
@@ -412,7 +459,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def handle_incoming(_), do: :error
def get_obj_helper(id) do
- if object = Object.get_by_ap_id(id), do: {:ok, object}, else: nil
+ if object = Object.normalize(id), do: {:ok, object}, else: nil
end
def set_reply_to_uri(%{"inReplyTo" => inReplyTo} = object) do
@@ -460,14 +507,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
# Mastodon Accept/Reject requires a non-normalized object containing the actor URIs,
# because of course it does.
def prepare_outgoing(%{"type" => "Accept"} = data) do
- follow_activity_id =
- if is_binary(data["object"]) do
- data["object"]
- else
- data["object"]["id"]
- end
-
- with follow_activity <- Activity.get_by_ap_id(follow_activity_id) do
+ with follow_activity <- Activity.normalize(data["object"]) do
object = %{
"actor" => follow_activity.actor,
"object" => follow_activity.data["object"],
@@ -485,14 +525,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end
def prepare_outgoing(%{"type" => "Reject"} = data) do
- follow_activity_id =
- if is_binary(data["object"]) do
- data["object"]
- else
- data["object"]["id"]
- end
-
- with follow_activity <- Activity.get_by_ap_id(follow_activity_id) do
+ with follow_activity <- Activity.normalize(data["object"]) do
object = %{
"actor" => follow_activity.actor,
"object" => follow_activity.data["object"],
diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex
index 64329b710..8b41a3bec 100644
--- a/lib/pleroma/web/activity_pub/utils.ex
+++ b/lib/pleroma/web/activity_pub/utils.ex
@@ -128,7 +128,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do
Inserts a full object if it is contained in an activity.
"""
def insert_full_object(%{"object" => %{"type" => type} = object_data})
- when is_map(object_data) and type in ["Note"] do
+ when is_map(object_data) and type in ["Article", "Note"] do
with {:ok, _} <- Object.create(object_data) do
:ok
end
diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex
index f4b2e0610..0b1d5a9fa 100644
--- a/lib/pleroma/web/activity_pub/views/user_view.ex
+++ b/lib/pleroma/web/activity_pub/views/user_view.ex
@@ -12,7 +12,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
def render("user.json", %{user: user}) do
{:ok, user} = WebFinger.ensure_keys_present(user)
{:ok, _, public_key} = Salmon.keys_from_pem(user.info["keys"])
- public_key = :public_key.pem_entry_encode(:RSAPublicKey, public_key)
+ public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key)
public_key = :public_key.pem_encode([public_key])
%{
@@ -98,9 +98,6 @@ defmodule Pleroma.Web.ActivityPub.UserView do
info = User.user_info(user)
params = %{
- "type" => ["Create", "Announce"],
- "actor_id" => user.ap_id,
- "whole_db" => true,
"limit" => "10"
}
@@ -111,10 +108,8 @@ defmodule Pleroma.Web.ActivityPub.UserView do
params
end
- activities = ActivityPub.fetch_public_activities(params)
- min_id = Enum.at(activities, 0).id
-
- activities = Enum.reverse(activities)
+ activities = ActivityPub.fetch_user_activities(user, nil, params)
+ min_id = Enum.at(Enum.reverse(activities), 0).id
max_id = Enum.at(activities, 0).id
collection =