total rebase
[anni] / lib / pleroma / web / common_api / activity_draft.ex
old mode 100755 (executable)
new mode 100644 (file)
index 63ed48a..bc46a8a
@@ -7,10 +7,14 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
   alias Pleroma.Conversation.Participation
   alias Pleroma.Object
   alias Pleroma.Web.ActivityPub.Builder
+  alias Pleroma.Web.ActivityPub.Visibility
   alias Pleroma.Web.CommonAPI
   alias Pleroma.Web.CommonAPI.Utils
 
   import Pleroma.Web.Gettext
+  import Pleroma.Web.Utils.Guards, only: [not_empty_string: 1]
+
+  @type t :: %__MODULE__{}
 
   defstruct valid?: true,
             errors: [],
@@ -22,6 +26,7 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
             attachments: [],
             in_reply_to: nil,
             in_reply_to_conversation: nil,
+            quote_post: nil,
             visibility: nil,
             expires_at: nil,
             extra: nil,
@@ -53,7 +58,9 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
     |> poll()
     |> with_valid(&in_reply_to/1)
     |> with_valid(&in_reply_to_conversation/1)
+    |> with_valid(&quote_post/1)
     |> with_valid(&visibility/1)
+    |> with_valid(&quoting_visibility/1)
     |> content()
     |> with_valid(&to_and_cc/1)
     |> with_valid(&context/1)
@@ -78,7 +85,7 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
   defp listen_object(draft) do
     object =
       draft.params
-      |> Map.take([:album, :artist, :title, :length])
+      |> Map.take([:album, :artist, :title, :length, :externalLink])
       |> Map.new(fn {key, value} -> {to_string(key), value} end)
       |> Map.put("type", "Audio")
       |> Map.put("to", draft.to)
@@ -132,6 +139,18 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
 
   defp in_reply_to(draft), do: draft
 
+  defp quote_post(%{params: %{quote_id: id}} = draft) when not_empty_string(id) do
+    case Activity.get_by_id_with_object(id) do
+      %Activity{} = activity ->
+        %__MODULE__{draft | quote_post: activity}
+
+      _ ->
+        draft
+    end
+  end
+
+  defp quote_post(draft), do: draft
+
   defp in_reply_to_conversation(draft) do
     in_reply_to_conversation = Participation.get(draft.params[:in_reply_to_conversation_id])
     %__MODULE__{draft | in_reply_to_conversation: in_reply_to_conversation}
@@ -147,6 +166,29 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
     end
   end
 
+  defp can_quote?(_draft, _object, visibility) when visibility in ~w(public unlisted local) do
+    true
+  end
+
+  defp can_quote?(draft, object, "private") do
+    draft.user.ap_id == object.data["actor"]
+  end
+
+  defp can_quote?(_, _, _) do
+    false
+  end
+
+  defp quoting_visibility(%{quote_post: %Activity{}} = draft) do
+    with %Object{} = object <- Object.normalize(draft.quote_post, fetch: false),
+         true <- can_quote?(draft, object, Visibility.get_visibility(object)) do
+      draft
+    else
+      _ -> add_error(draft, dgettext("errors", "Cannot quote private message"))
+    end
+  end
+
+  defp quoting_visibility(draft), do: draft
+
   defp expires_at(draft) do
     case CommonAPI.check_expiry_date(draft.params[:expires_in]) do
       {:ok, expires_at} -> %__MODULE__{draft | expires_at: expires_at}
@@ -164,12 +206,15 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
     end
   end
 
-  defp content(draft) do
+  defp content(%{mentions: mentions} = draft) do
     {content_html, mentioned_users, tags} = Utils.make_content_html(draft)
 
+    mentioned_ap_ids =
+      Enum.map(mentioned_users, fn {_, mentioned_user} -> mentioned_user.ap_id end)
+
     mentions =
-      mentioned_users
-      |> Enum.map(fn {_, mentioned_user} -> mentioned_user.ap_id end)
+      mentions
+      |> Kernel.++(mentioned_ap_ids)
       |> Utils.get_addressed_users(draft.params[:to])
 
     %__MODULE__{draft | content_html: content_html, mentions: mentions, tags: tags}