Merge branch 'fix/missing_emoji_steal_dir' into 'develop'
authorlain <lain@soykaf.club>
Fri, 8 Jan 2021 13:10:49 +0000 (13:10 +0000)
committerlain <lain@soykaf.club>
Fri, 8 Jan 2021 13:10:49 +0000 (13:10 +0000)
Create dir for EmojiStealPolicy automatically

See merge request pleroma/pleroma!3218

119 files changed:
CHANGELOG.md
config/config.exs
config/description.exs
config/emoji.txt
config/test.exs
docs/API/admin_api.md
docs/API/differences_in_mastoapi_responses.md
lib/pleroma/activity.ex
lib/pleroma/activity/ir/topics.ex
lib/pleroma/conversation.ex
lib/pleroma/emails/user_email.ex
lib/pleroma/emoji/formatter.ex
lib/pleroma/gopher/server.ex
lib/pleroma/html.ex
lib/pleroma/logging.ex [new file with mode: 0644]
lib/pleroma/notification.ex
lib/pleroma/object.ex
lib/pleroma/object/fetcher.ex
lib/pleroma/user.ex
lib/pleroma/web/activity_pub/activity_pub.ex
lib/pleroma/web/activity_pub/activity_pub/streaming.ex [new file with mode: 0644]
lib/pleroma/web/activity_pub/activity_pub_controller.ex
lib/pleroma/web/activity_pub/builder.ex
lib/pleroma/web/activity_pub/mrf/ensure_re_prepended.ex
lib/pleroma/web/activity_pub/object_validator.ex
lib/pleroma/web/activity_pub/publisher.ex
lib/pleroma/web/activity_pub/side_effects.ex
lib/pleroma/web/activity_pub/transmogrifier.ex
lib/pleroma/web/activity_pub/views/object_view.ex
lib/pleroma/web/activity_pub/views/user_view.ex
lib/pleroma/web/admin_api/controllers/admin_api_controller.ex
lib/pleroma/web/admin_api/views/account_view.ex
lib/pleroma/web/admin_api/views/moderation_log_view.ex
lib/pleroma/web/admin_api/views/report_view.ex
lib/pleroma/web/api_spec/operations/account_operation.ex
lib/pleroma/web/api_spec/schemas/account.ex
lib/pleroma/web/common_api.ex
lib/pleroma/web/common_api/utils.ex
lib/pleroma/web/embed_controller.ex
lib/pleroma/web/feed/feed_view.ex
lib/pleroma/web/mastodon_api/controllers/account_controller.ex
lib/pleroma/web/mastodon_api/controllers/status_controller.ex
lib/pleroma/web/mastodon_api/views/account_view.ex
lib/pleroma/web/mastodon_api/views/notification_view.ex
lib/pleroma/web/mastodon_api/views/status_view.ex
lib/pleroma/web/o_status/o_status_controller.ex
lib/pleroma/web/pleroma_api/controllers/chat_controller.ex
lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex
lib/pleroma/web/pleroma_api/views/backup_view.ex
lib/pleroma/web/pleroma_api/views/scrobble_view.ex
lib/pleroma/web/plugs/uploaded_media.ex
lib/pleroma/web/push/impl.ex
lib/pleroma/web/rich_media/helpers.ex
lib/pleroma/web/static_fe/static_fe_controller.ex
lib/pleroma/web/streamer.ex
lib/pleroma/web/web_finger.ex
mix.exs
mix.lock
priv/static/emoji/dino walking.gif [new file with mode: 0644]
test/mix/tasks/pleroma/user_test.exs
test/pleroma/activity_test.exs
test/pleroma/bbs/handler_test.exs
test/pleroma/conversation/participation_test.exs
test/pleroma/conversation_test.exs
test/pleroma/html_test.exs
test/pleroma/object_test.exs
test/pleroma/user/welcome_chat_message_test.exs
test/pleroma/user/welcome_message_test.exs
test/pleroma/user_test.exs
test/pleroma/web/activity_pub/activity_pub_controller_test.exs
test/pleroma/web/activity_pub/activity_pub_test.exs
test/pleroma/web/activity_pub/object_validators/announce_validation_test.exs
test/pleroma/web/activity_pub/object_validators/chat_validation_test.exs
test/pleroma/web/activity_pub/publisher_test.exs
test/pleroma/web/activity_pub/side_effects/delete_test.exs [new file with mode: 0644]
test/pleroma/web/activity_pub/side_effects_test.exs
test/pleroma/web/activity_pub/transmogrifier/announce_handling_test.exs
test/pleroma/web/activity_pub/transmogrifier/answer_handling_test.exs
test/pleroma/web/activity_pub/transmogrifier/article_handling_test.exs
test/pleroma/web/activity_pub/transmogrifier/audio_handling_test.exs
test/pleroma/web/activity_pub/transmogrifier/delete_handling_test.exs
test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs
test/pleroma/web/activity_pub/transmogrifier/question_handling_test.exs
test/pleroma/web/activity_pub/transmogrifier/video_handling_test.exs
test/pleroma/web/activity_pub/transmogrifier_test.exs
test/pleroma/web/activity_pub/utils_test.exs
test/pleroma/web/activity_pub/views/object_view_test.exs
test/pleroma/web/activity_pub/views/user_view_test.exs
test/pleroma/web/admin_api/controllers/admin_api_controller_test.exs
test/pleroma/web/admin_api/controllers/chat_controller_test.exs
test/pleroma/web/admin_api/controllers/user_controller_test.exs
test/pleroma/web/admin_api/views/account_view_test.exs [new file with mode: 0644]
test/pleroma/web/admin_api/views/moderation_log_view_test.exs
test/pleroma/web/admin_api/views/report_view_test.exs
test/pleroma/web/common_api_test.exs
test/pleroma/web/feed/tag_controller_test.exs
test/pleroma/web/feed/user_controller_test.exs
test/pleroma/web/mastodon_api/controllers/account_controller_test.exs
test/pleroma/web/mastodon_api/controllers/poll_controller_test.exs
test/pleroma/web/mastodon_api/controllers/search_controller_test.exs
test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
test/pleroma/web/mastodon_api/update_credentials_test.exs
test/pleroma/web/mastodon_api/views/account_view_test.exs
test/pleroma/web/mastodon_api/views/notification_view_test.exs
test/pleroma/web/mastodon_api/views/poll_view_test.exs
test/pleroma/web/mastodon_api/views/status_view_test.exs
test/pleroma/web/o_status/o_status_controller_test.exs
test/pleroma/web/pleroma_api/controllers/chat_controller_test.exs
test/pleroma/web/pleroma_api/views/backup_view_test.exs [new file with mode: 0644]
test/pleroma/web/pleroma_api/views/chat_message_reference_view_test.exs
test/pleroma/web/pleroma_api/views/chat_view_test.exs
test/pleroma/web/push/impl_test.exs
test/pleroma/web/streamer_test.exs
test/pleroma/web/web_finger/web_finger_controller_test.exs
test/pleroma/workers/scheduled_activity_worker_test.exs
test/support/conn_case.ex
test/support/data_case.ex
test/support/factory.ex
test/support/mocks.ex

index 716fbb75d5ef411ce068d1c04e9a8f3b12925445..25b24bf07a660bb912f7122748fab7a0f8d9bcfb 100644 (file)
@@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 - **Breaking:** Changed `mix pleroma.user toggle_confirmed` to `mix pleroma.user confirm`
 - Search: When using Postgres 11+, Pleroma will use the `websearch_to_tsvector` function to parse search queries.
 - Emoji: Support the full Unicode 13.1 set of Emoji for reactions, plus regional indicators.
+- Admin API: Reports now ordered by newest
 
 ### Added
 
@@ -29,6 +30,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 - Mix tasks to help with displaying and removing ConfigDB entries. See `mix pleroma.config`.
 - OAuth form improvements: users are remembered by their cookie, the CSS is overridable by the admin, and the style has been improved.
 - OAuth improvements and fixes: more secure session-based authentication (by token that could be revoked anytime), ability to revoke belonging OAuth token from any client etc.
+- Ability to set ActivityPub aliases for follower migration.
 
 <details>
   <summary>API Changes</summary>
index d6d116314e3f9a8a965e121b19af7b19bfaccefa..7b14fbfe5af3499139c68202d7f407adf9a9ac04 100644 (file)
@@ -63,14 +63,6 @@ config :pleroma, Pleroma.Upload,
   filters: [Pleroma.Upload.Filter.Dedupe],
   link_name: false,
   proxy_remote: false,
-  proxy_opts: [
-    redirect_on_failure: false,
-    max_body_length: 25 * 1_048_576,
-    http: [
-      follow_redirect: true,
-      pool: :upload
-    ]
-  ],
   filename_display_max_length: 30,
   default_description: nil
 
index cf004f0cfe32426cc916a3698e48e2a7348a81a7..f438a88abc10a394670705f9aca9fb9a77a8e67d 100644 (file)
@@ -101,74 +101,10 @@ config :pleroma, :config_description, [
       %{
         key: :proxy_remote,
         type: :boolean,
-        description:
-          "If enabled, requests to media stored using a remote uploader will be proxied instead of being redirected"
-      },
-      %{
-        key: :proxy_opts,
-        label: "Proxy Options",
-        type: :keyword,
-        description: "Options for Pleroma.ReverseProxy",
-        suggestions: [
-          redirect_on_failure: false,
-          max_body_length: 25 * 1_048_576,
-          http: [
-            follow_redirect: true,
-            pool: :media
-          ]
-        ],
-        children: [
-          %{
-            key: :redirect_on_failure,
-            type: :boolean,
-            description:
-              "Redirects the client to the real remote URL if there's any HTTP errors. " <>
-                "Any error during body processing will not be redirected as the response is chunked."
-          },
-          %{
-            key: :max_body_length,
-            type: :integer,
-            description:
-              "Limits the content length to be approximately the " <>
-                "specified length. It is validated with the `content-length` header and also verified when proxying."
-          },
-          %{
-            key: :http,
-            label: "HTTP",
-            type: :keyword,
-            description: "HTTP options",
-            children: [
-              %{
-                key: :adapter,
-                type: :keyword,
-                description: "Adapter specific options",
-                children: [
-                  %{
-                    key: :ssl_options,
-                    type: :keyword,
-                    label: "SSL Options",
-                    description: "SSL options for HTTP adapter",
-                    children: [
-                      %{
-                        key: :versions,
-                        type: {:list, :atom},
-                        description: "List of TLS versions to use",
-                        suggestions: [:tlsv1, ":tlsv1.1", ":tlsv1.2"]
-                      }
-                    ]
-                  }
-                ]
-              },
-              %{
-                key: :proxy_url,
-                label: "Proxy URL",
-                type: [:string, :tuple],
-                description: "Proxy URL",
-                suggestions: ["127.0.0.1:8123", {:socks5, :localhost, 9050}]
-              }
-            ]
-          }
-        ]
+        description: """
+        Proxy requests to the remote uploader.\n
+        Useful if media upload endpoint is not internet accessible.
+        """
       },
       %{
         key: :filename_display_max_length,
@@ -1550,7 +1486,7 @@ config :pleroma, :config_description, [
       %{
         key: :enabled,
         type: :boolean,
-        description: "Enables proxying of remote media to the instance's proxy"
+        description: "Enables proxying of remote media via the instance's proxy"
       },
       %{
         key: :base_url,
@@ -1587,80 +1523,41 @@ config :pleroma, :config_description, [
       },
       %{
         key: :proxy_opts,
-        label: "Proxy Options",
+        label: "Advanced MediaProxy Options",
         type: :keyword,
-        description: "Options for Pleroma.ReverseProxy",
+        description: "Internal Pleroma.ReverseProxy settings",
         suggestions: [
           redirect_on_failure: false,
           max_body_length: 25 * 1_048_576,
-          max_read_duration: 30_000,
-          http: [
-            follow_redirect: true,
-            pool: :media
-          ]
+          max_read_duration: 30_000
         ],
         children: [
           %{
             key: :redirect_on_failure,
             type: :boolean,
-            description:
-              "Redirects the client to the real remote URL if there's any HTTP errors. " <>
-                "Any error during body processing will not be redirected as the response is chunked."
+            description: """
+            Redirects the client to the origin server upon encountering HTTP errors.\n
+            Note that files larger than Max Body Length will trigger an error. (e.g., Peertube videos)\n\n
+            **WARNING:** This setting will allow larger files to be accessed, but exposes the\n
+            IP addresses of your users to the other servers, bypassing the MediaProxy.
+            """
           },
           %{
             key: :max_body_length,
             type: :integer,
-            description:
-              "Limits the content length to be approximately the " <>
-                "specified length. It is validated with the `content-length` header and also verified when proxying."
+            description: "Maximum file size allowed through the Pleroma MediaProxy cache."
           },
           %{
             key: :max_read_duration,
             type: :integer,
-            description: "Timeout (in milliseconds) of GET request to remote URI."
-          },
-          %{
-            key: :http,
-            label: "HTTP",
-            type: :keyword,
-            description: "HTTP options",
-            children: [
-              %{
-                key: :adapter,
-                type: :keyword,
-                description: "Adapter specific options",
-                children: [
-                  %{
-                    key: :ssl_options,
-                    type: :keyword,
-                    label: "SSL Options",
-                    description: "SSL options for HTTP adapter",
-                    children: [
-                      %{
-                        key: :versions,
-                        type: {:list, :atom},
-                        description: "List of TLS version to use",
-                        suggestions: [:tlsv1, ":tlsv1.1", ":tlsv1.2"]
-                      }
-                    ]
-                  }
-                ]
-              },
-              %{
-                key: :proxy_url,
-                label: "Proxy URL",
-                type: [:string, :tuple],
-                description: "Proxy URL",
-                suggestions: ["127.0.0.1:8123", {:socks5, :localhost, 9050}]
-              }
-            ]
+            description: "Timeout (in milliseconds) of GET request to the remote URI."
           }
         ]
       },
       %{
         key: :whitelist,
         type: {:list, :string},
-        description: "List of hosts with scheme to bypass the mediaproxy",
+        description: "List of hosts with scheme to bypass the MediaProxy",
         suggestions: ["http://example.com"]
       }
     ]
index 200768ad1d0367fbb06b7321d434f7637c8481fb..a2c5add2e873728aef8e878a04bc74d4a50c4e03 100644 (file)
@@ -1,2 +1,4 @@
 firefox, /emoji/Firefox.gif, Gif,Fun
 blank, /emoji/blank.png, Fun
+dinosaur, /emoji/dino walking.gif, Gif
+external_emoji, https://example.com/emoji.png
index a858815921f65c81dcc60b5de679cb3182803dc5..7fc4574633fc704a48ec54dd49bdb05c1357d8e8 100644 (file)
@@ -134,6 +134,10 @@ config :pleroma, :pipeline,
 
 config :pleroma, :cachex, provider: Pleroma.CachexMock
 
+config :pleroma, :side_effects,
+  ap_streamer: Pleroma.Web.ActivityPub.ActivityPubMock,
+  logger: Pleroma.LoggerMock
+
 if File.exists?("./config/test.secret.exs") do
   import_config "test.secret.exs"
 else
index 266f8cef8e97ba546708d17dc07b9c2ebdeec697..5253dc6689cce569d3cb78514d9bf7969e49e167 100644 (file)
@@ -1123,6 +1123,7 @@ Loads json generated from `config/descriptions.exs`.
 ```json
 [
   {
+    "id": 1234,
     "data": {
       "actor": {
         "id": 1,
index 1b197e073efdde973358c72f4edd68f953a1ea85..84430408b4c3e9fca74f05e476e02eb5622c248e 100644 (file)
@@ -206,6 +206,7 @@ Additional parameters can be added to the JSON body/Form data:
 - `pleroma_settings_store` - Opaque user settings to be saved on the backend.
 - `skip_thread_containment` - if true, skip filtering out broken threads
 - `allow_following_move` - if true, allows automatically follow moved following accounts
+- `also_known_as` - array of ActivityPub IDs, needed for following move
 - `pleroma_background_image` - sets the background image of the user. Can be set to "" (an empty string) to reset.
 - `discoverable` - if true, external services (search bots) etc. are allowed to index / list the account (regardless of this setting, user will still appear in regular search results).
 - `actor_type` - the type of this account.
index 9d970a80838fa29c27f1f98e0073f22713aba84c..62fa9cca3b4e5f06e6352d687836b8f161f624db 100644 (file)
@@ -274,7 +274,7 @@ defmodule Pleroma.Activity do
   defp get_in_reply_to_activity_from_object(_), do: nil
 
   def get_in_reply_to_activity(%Activity{} = activity) do
-    get_in_reply_to_activity_from_object(Object.normalize(activity))
+    get_in_reply_to_activity_from_object(Object.normalize(activity, fetch: false))
   end
 
   def normalize(obj) when is_map(obj), do: get_by_ap_id_with_object(obj["id"])
index fe2e8cb5c900d7b84f0e92bc1ba42a74c85d685b..6a26d7fdd3c088a0492c20bfdcb25c68e42a1e07 100644 (file)
@@ -8,7 +8,7 @@ defmodule Pleroma.Activity.Ir.Topics do
 
   def get_activity_topics(activity) do
     activity
-    |> Object.normalize()
+    |> Object.normalize(fetch: false)
     |> generate_topics(activity)
     |> List.flatten()
   end
index 77933f0bec8eaee3163fc82a729d91def78c9aa4..e152590917c79edf2a79c55c6c5f4c4028b4911f 100644 (file)
@@ -5,6 +5,7 @@
 defmodule Pleroma.Conversation do
   alias Pleroma.Conversation.Participation
   alias Pleroma.Conversation.Participation.RecipientShip
+  alias Pleroma.Object
   alias Pleroma.Repo
   alias Pleroma.User
   use Ecto.Schema
@@ -58,7 +59,7 @@ defmodule Pleroma.Conversation do
   def create_or_bump_for(activity, opts \\ []) do
     with true <- Pleroma.Web.ActivityPub.Visibility.is_direct?(activity),
          "Create" <- activity.data["type"],
-         object <- Pleroma.Object.normalize(activity),
+         %Object{} = object <- Object.normalize(activity, fetch: false),
          true <- object.data["type"] in ["Note", "Question"],
          ap_id when is_binary(ap_id) and byte_size(ap_id) > 0 <- object.data["context"] do
       {:ok, conversation} = create_for_ap_id(ap_id)
index d3625dbf2bb7bc54f3f27a901261460570eff0a8..2b51d5b0521ddf987db3d2f99284d177cb26efea 100644 (file)
@@ -119,7 +119,7 @@ defmodule Pleroma.Emails.UserEmail do
       notifications
       |> Enum.filter(&(&1.activity.data["type"] == "Create"))
       |> Enum.map(fn notification ->
-        object = Pleroma.Object.normalize(notification.activity)
+        object = Pleroma.Object.normalize(notification.activity, fetch: false)
 
         if not is_nil(object) do
           object = update_in(object.data["content"], &format_links/1)
@@ -142,7 +142,7 @@ defmodule Pleroma.Emails.UserEmail do
         if not is_nil(from) do
           %{
             data: notification,
-            object: Pleroma.Object.normalize(notification.activity),
+            object: Pleroma.Object.normalize(notification.activity, fetch: false),
             from: User.get_by_ap_id(notification.activity.actor)
           }
         end
index dc45b8a38ed4a0bb6834dd456705735752c16a9d..992b20e1289efb7f5ad35d165c581d747cb22f75 100644 (file)
@@ -5,6 +5,7 @@
 defmodule Pleroma.Emoji.Formatter do
   alias Pleroma.Emoji
   alias Pleroma.HTML
+  alias Pleroma.Web
   alias Pleroma.Web.MediaProxy
 
   def emojify(text) do
@@ -43,7 +44,7 @@ defmodule Pleroma.Emoji.Formatter do
     Emoji.get_all()
     |> Enum.filter(fn {emoji, %Emoji{}} -> String.contains?(text, ":#{emoji}:") end)
     |> Enum.reduce(%{}, fn {name, %Emoji{file: file}}, acc ->
-      Map.put(acc, name, "#{Pleroma.Web.Endpoint.static_url()}#{file}")
+      Map.put(acc, name, to_string(URI.merge(Web.base_url(), file)))
     end)
   end
 
index e9f54c4c0077ec276131d69054ed02d69690cd95..8ac8d18c1dafaa09c9b7226388398b50d4555449 100644 (file)
@@ -76,7 +76,7 @@ defmodule Pleroma.Gopher.Server.ProtocolHandler do
     |> Enum.map(fn activity ->
       user = User.get_cached_by_ap_id(activity.data["actor"])
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
       like_count = object.data["like_count"] || 0
       announcement_count = object.data["announcement_count"] || 0
 
index c848c782c3c79e731d70553e04009bf23992d3d6..c5ece7350247e9fc69e8fa383063cad79d723622 100644 (file)
@@ -59,7 +59,7 @@ defmodule Pleroma.HTML do
     key = "#{key}#{generate_scrubber_signature(scrubbers)}|#{activity.id}"
 
     @cachex.fetch!(:scrubber_cache, key, fn _key ->
-      object = Pleroma.Object.normalize(activity)
+      object = Pleroma.Object.normalize(activity, fetch: false)
       ensure_scrubbed_html(content, scrubbers, object.data["fake"] || false, callback)
     end)
   end
diff --git a/lib/pleroma/logging.ex b/lib/pleroma/logging.ex
new file mode 100644 (file)
index 0000000..37b201c
--- /dev/null
@@ -0,0 +1,7 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Logging do
+  @callback error(String.t()) :: any()
+end
index dd7a1c82405f6e8e8ed5fd926bfeb2d2e5a494b5..4efea9f7dafb62037c818cf8692f53446dba1943 100644 (file)
@@ -358,7 +358,7 @@ defmodule Pleroma.Notification do
   def create_notifications(activity, options \\ [])
 
   def create_notifications(%Activity{data: %{"to" => _, "type" => "Create"}} = activity, options) do
-    object = Object.normalize(activity, false)
+    object = Object.normalize(activity, fetch: false)
 
     if object && object.data["type"] == "Answer" do
       {:ok, []}
@@ -625,7 +625,7 @@ defmodule Pleroma.Notification do
   def skip?(:filtered, %{data: %{"type" => type}}, _) when type in ["Follow", "Move"], do: false
 
   def skip?(:filtered, activity, user) do
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
 
     cond do
       is_nil(object) ->
index b4a994da98320256d54759d1d08e482ecb3231a3..4fb4ec36406fe44d6b7a5dcb83c3643782b36f28 100644 (file)
@@ -108,39 +108,42 @@ defmodule Pleroma.Object do
     Logger.debug("Backtrace: #{inspect(Process.info(:erlang.self(), :current_stacktrace))}")
   end
 
-  def normalize(_, fetch_remote \\ true, options \\ [])
+  def normalize(_, options \\ [fetch: false])
 
   # If we pass an Activity to Object.normalize(), we can try to use the preloaded object.
   # Use this whenever possible, especially when walking graphs in an O(N) loop!
-  def normalize(%Object{} = object, _, _), do: object
-  def normalize(%Activity{object: %Object{} = object}, _, _), do: object
+  def normalize(%Object{} = object, _), do: object
+  def normalize(%Activity{object: %Object{} = object}, _), do: object
 
   # A hack for fake activities
-  def normalize(%Activity{data: %{"object" => %{"fake" => true} = data}}, _, _) do
+  def normalize(%Activity{data: %{"object" => %{"fake" => true} = data}}, _) do
     %Object{id: "pleroma:fake_object_id", data: data}
   end
 
   # No preloaded object
-  def normalize(%Activity{data: %{"object" => %{"id" => ap_id}}}, fetch_remote, _) do
+  def normalize(%Activity{data: %{"object" => %{"id" => ap_id}}}, options) do
     warn_on_no_object_preloaded(ap_id)
-    normalize(ap_id, fetch_remote)
+    normalize(ap_id, options)
   end
 
   # No preloaded object
-  def normalize(%Activity{data: %{"object" => ap_id}}, fetch_remote, _) do
+  def normalize(%Activity{data: %{"object" => ap_id}}, options) do
     warn_on_no_object_preloaded(ap_id)
-    normalize(ap_id, fetch_remote)
+    normalize(ap_id, options)
   end
 
   # Old way, try fetching the object through cache.
-  def normalize(%{"id" => ap_id}, fetch_remote, _), do: normalize(ap_id, fetch_remote)
-  def normalize(ap_id, false, _) when is_binary(ap_id), do: get_cached_by_ap_id(ap_id)
+  def normalize(%{"id" => ap_id}, options), do: normalize(ap_id, options)
 
-  def normalize(ap_id, true, options) when is_binary(ap_id) do
-    Fetcher.fetch_object_from_id!(ap_id, options)
+  def normalize(ap_id, options) when is_binary(ap_id) do
+    if Keyword.get(options, :fetch) do
+      Fetcher.fetch_object_from_id!(ap_id, options)
+    else
+      get_cached_by_ap_id(ap_id)
+    end
   end
 
-  def normalize(_, _, _), do: nil
+  def normalize(_, _), do: nil
 
   # Owned objects can only be accessed by their owner
   def authorize_access(%Object{data: %{"actor" => actor}}, %User{ap_id: ap_id}) do
@@ -285,7 +288,7 @@ defmodule Pleroma.Object do
   end
 
   def increase_vote_count(ap_id, name, actor) do
-    with %Object{} = object <- Object.normalize(ap_id),
+    with %Object{} = object <- Object.normalize(ap_id, fetch: false),
          "Question" <- object.data["type"] do
       key = if poll_is_multiple?(object), do: "anyOf", else: "oneOf"
 
@@ -326,7 +329,7 @@ defmodule Pleroma.Object do
   end
 
   def replies(object, opts \\ []) do
-    object = Object.normalize(object)
+    object = Object.normalize(object, fetch: false)
 
     query =
       Object
index 20d8f687d19d940c28f75e43d23efbf4a4bb96c6..18c383881f84b99472d10c659284ab38ceedde6e 100644 (file)
@@ -83,13 +83,13 @@ defmodule Pleroma.Object.Fetcher do
     with {_, nil} <- {:fetch_object, Object.get_cached_by_ap_id(id)},
          {_, true} <- {:allowed_depth, Federator.allowed_thread_distance?(options[:depth])},
          {_, {:ok, data}} <- {:fetch, fetch_and_contain_remote_object_from_id(id)},
-         {_, nil} <- {:normalize, Object.normalize(data, false)},
+         {_, nil} <- {:normalize, Object.normalize(data, fetch: false)},
          params <- prepare_activity_params(data),
          {_, :ok} <- {:containment, Containment.contain_origin(id, params)},
          {_, {:ok, activity}} <-
            {:transmogrifier, Transmogrifier.handle_incoming(params, options)},
          {_, _data, %Object{} = object} <-
-           {:object, data, Object.normalize(activity, false)} do
+           {:object, data, Object.normalize(activity, fetch: false)} do
       {:ok, object}
     else
       {:allowed_depth, false} ->
index bd4801058b45243eecd0551125d5b71b90303465..52730fd8d63654b2c3ae8302a011a2b0d61a813f 100644 (file)
@@ -142,7 +142,7 @@ defmodule Pleroma.User do
     field(:allow_following_move, :boolean, default: true)
     field(:skip_thread_containment, :boolean, default: false)
     field(:actor_type, :string, default: "Person")
-    field(:also_known_as, {:array, :string}, default: [])
+    field(:also_known_as, {:array, ObjectValidators.ObjectID}, default: [])
     field(:inbox, :string)
     field(:shared_inbox, :string)
     field(:accepts_chat_messages, :boolean, default: nil)
@@ -515,6 +515,7 @@ defmodule Pleroma.User do
         :hide_follows_count,
         :hide_favorites,
         :allow_following_move,
+        :also_known_as,
         :background,
         :show_role,
         :skip_thread_containment,
@@ -523,7 +524,6 @@ defmodule Pleroma.User do
         :pleroma_settings_store,
         :is_discoverable,
         :actor_type,
-        :also_known_as,
         :accepts_chat_messages
       ]
     )
index 5059bff03b3d88dc1b377ece8e1a2b05c8037058..8c2610eeb377ac192105d0b042ca73f8f96e740a 100644 (file)
@@ -33,6 +33,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
   require Pleroma.Constants
 
   @behaviour Pleroma.Web.ActivityPub.ActivityPub.Persisting
+  @behaviour Pleroma.Web.ActivityPub.ActivityPub.Streaming
 
   defp get_recipients(%{"type" => "Create"} = data) do
     to = Map.get(data, "to", [])
@@ -224,6 +225,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     Streamer.stream("participation", participations)
   end
 
+  @impl true
   def stream_out_participations(%Object{data: %{"context" => context}}, user) do
     with %Conversation{} = conversation <- Conversation.get_for_ap_id(context) do
       conversation = Repo.preload(conversation, :participations)
@@ -240,8 +242,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     end
   end
 
+  @impl true
   def stream_out_participations(_, _), do: :noop
 
+  @impl true
   def stream_out(%Activity{data: %{"type" => data_type}} = activity)
       when data_type in ["Create", "Announce", "Delete"] do
     activity
@@ -249,6 +253,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     |> Streamer.stream(activity)
   end
 
+  @impl true
   def stream_out(_activity) do
     :noop
   end
@@ -603,12 +608,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
         |> Map.put(:muting_user, reading_user)
       end
 
+    pagination_type = Map.get(params, :pagination_type) || :keyset
+
     %{
       godmode: params[:godmode],
       reading_user: reading_user
     }
     |> user_activities_recipients()
-    |> fetch_activities(params)
+    |> fetch_activities(params, pagination_type)
     |> Enum.reverse()
   end
 
diff --git a/lib/pleroma/web/activity_pub/activity_pub/streaming.ex b/lib/pleroma/web/activity_pub/activity_pub/streaming.ex
new file mode 100644 (file)
index 0000000..30009f2
--- /dev/null
@@ -0,0 +1,12 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.ActivityPub.Streaming do
+  alias Pleroma.Activity
+  alias Pleroma.Object
+  alias Pleroma.User
+
+  @callback stream_out(Activity.t()) :: any()
+  @callback stream_out_participations(Object.t(), User.t()) :: any()
+end
index 7e5647f8fcb9d0f18f77f961b2fc3647e759c54e..8d9b69cc79163f863673da8ef6500d1c666f56fb 100644 (file)
@@ -128,7 +128,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
   end
 
   defp maybe_set_tracking_data(conn, %Activity{data: %{"type" => "Create"}} = activity) do
-    object_id = Object.normalize(activity).id
+    object_id = Object.normalize(activity, fetch: false).id
     assign(conn, :tracking_fun_data, object_id)
   end
 
@@ -434,7 +434,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
   end
 
   defp handle_user_activity(%User{} = user, %{"type" => "Delete"} = params) do
-    with %Object{} = object <- Object.normalize(params["object"]),
+    with %Object{} = object <- Object.normalize(params["object"], fetch: false),
          true <- user.is_moderator || user.ap_id == object.data["actor"],
          {:ok, delete_data, _} <- Builder.delete(user, object.data["id"]),
          {:ok, delete, _} <- Pipeline.common_pipeline(delete_data, local: true) do
@@ -445,7 +445,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
   end
 
   defp handle_user_activity(%User{} = user, %{"type" => "Like"} = params) do
-    with %Object{} = object <- Object.normalize(params["object"]),
+    with %Object{} = object <- Object.normalize(params["object"], fetch: false),
          {_, {:ok, like_object, meta}} <- {:build_object, Builder.like(user, object)},
          {_, {:ok, %Activity{} = activity, _meta}} <-
            {:common_pipeline,
index e99f6fd83c02031435b91849b88afae3af7fd5df..74ddc25061f62dc03c54acf103dad464ae315b5a 100644 (file)
@@ -80,7 +80,7 @@ defmodule Pleroma.Web.ActivityPub.Builder do
 
   @spec delete(User.t(), String.t()) :: {:ok, map(), keyword()}
   def delete(actor, object_id) do
-    object = Object.normalize(object_id, false)
+    object = Object.normalize(object_id, fetch: false)
 
     user = !object && User.get_cached_by_ap_id(object_id)
 
index 3bf70b8946b90f9248607d15ceaecbb3e63cc7e2..c8c40c70255205819d44d73fdb96bc8f41e691d9 100644 (file)
@@ -31,7 +31,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.EnsureRePrepended do
       when is_map(child_object) do
     child =
       child_object["inReplyTo"]
-      |> Object.normalize(child_object["inReplyTo"])
+      |> Object.normalize(fetch: false)
       |> filter_by_summary(child_object)
 
     object = Map.put(object, "object", child)
index ce8e7341b782e86b7de2535d4156e192ca1a341a..244753c02937916ea547ba3f99061d946ff7eca6 100644 (file)
@@ -288,7 +288,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
 
   def fetch_actor_and_object(object) do
     fetch_actor(object)
-    Object.normalize(object["object"], true)
+    Object.normalize(object["object"], fetch: true)
     :ok
   end
 end
index 5ab3562bfe090e47e48f8811bb7ffec526e21af4..dca28e5bd1fb533776bb281d7df8fe076ef091ed 100644 (file)
@@ -129,7 +129,7 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
 
     fetchers =
       with %Activity{data: %{"type" => "Delete"}} <- activity,
-           %Object{id: object_id} <- Object.normalize(activity),
+           %Object{id: object_id} <- Object.normalize(activity, fetch: false),
            fetchers <- User.get_delivered_users_by_object_id(object_id),
            _ <- Delivery.delete_all_by_object_id(object_id) do
         fetchers
index 55c99ad0cabf3da38ae35494fb192ba8b035f9a6..76287f2744e2da71b113314749fade022be1c203 100644 (file)
@@ -28,6 +28,8 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
   require Logger
 
   @cachex Pleroma.Config.get([:cachex, :provider], Cachex)
+  @ap_streamer Pleroma.Config.get([:side_effects, :ap_streamer], ActivityPub)
+  @logger Pleroma.Config.get([:side_effects, :logger], Logger)
 
   @behaviour Pleroma.Web.ActivityPub.SideEffects.Handling
 
@@ -268,7 +270,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
   @impl true
   def handle(%{data: %{"type" => "Delete", "object" => deleted_object}} = object, meta) do
     deleted_object =
-      Object.normalize(deleted_object, false) ||
+      Object.normalize(deleted_object, fetch: false) ||
         User.get_cached_by_ap_id(deleted_object)
 
     result =
@@ -287,12 +289,12 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
 
             MessageReference.delete_for_object(deleted_object)
 
-            ActivityPub.stream_out(object)
-            ActivityPub.stream_out_participations(deleted_object, user)
+            @ap_streamer.stream_out(object)
+            @ap_streamer.stream_out_participations(deleted_object, user)
             :ok
           else
             {:actor, _} ->
-              Logger.error("The object doesn't have an actor: #{inspect(deleted_object)}")
+              @logger.error("The object doesn't have an actor: #{inspect(deleted_object)}")
               :no_object_actor
           end
 
index 565d324330b751ca35bc65dfbdb3589e993f6a4c..99cdf91ab1bc663e6e5c29c9cb61ca0f024426c3 100644 (file)
@@ -653,7 +653,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
 
   @spec get_obj_helper(String.t(), Keyword.t()) :: {:ok, Object.t()} | nil
   def get_obj_helper(id, options \\ []) do
-    case Object.normalize(id, true, options) do
+    options = Keyword.put(options, :fetch, true)
+
+    case Object.normalize(id, options) do
       %Object{} = object -> {:ok, object}
       _ -> nil
     end
@@ -672,7 +674,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
              "actor" => attributed_to,
              "object" => data
            }) do
-      {:ok, Object.normalize(activity)}
+      {:ok, Object.normalize(activity, fetch: false)}
     else
       _ -> get_obj_helper(object_id)
     end
@@ -763,7 +765,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
       when activity_type in ["Create", "Listen"] do
     object =
       object_id
-      |> Object.normalize()
+      |> Object.normalize(fetch: false)
       |> Map.get(:data)
       |> prepare_object
 
@@ -779,7 +781,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
   def prepare_outgoing(%{"type" => "Announce", "actor" => ap_id, "object" => object_id} = data) do
     object =
       object_id
-      |> Object.normalize()
+      |> Object.normalize(fetch: false)
 
     data =
       if Visibility.is_private?(object) && object.data["actor"] == ap_id do
@@ -919,7 +921,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
 
   defp build_emoji_tag({name, url}) do
     %{
-      "icon" => %{"url" => url, "type" => "Image"},
+      "icon" => %{"url" => "#{URI.encode(url)}", "type" => "Image"},
       "name" => ":" <> name <> ":",
       "type" => "Emoji",
       "updated" => "1970-01-01T00:00:00Z",
index e555e9999fbf841f963bd5fb67b050838f461092..44bc5621ba04cc2ad6a019e7af254fdea722d695 100644 (file)
@@ -18,7 +18,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectView do
   def render("object.json", %{object: %Activity{data: %{"type" => activity_type}} = activity})
       when activity_type in ["Create", "Listen"] do
     base = Pleroma.Web.ActivityPub.Utils.make_json_ld_header()
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
 
     additional =
       Transmogrifier.prepare_object(activity.data)
@@ -29,7 +29,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectView do
 
   def render("object.json", %{object: %Activity{} = activity}) do
     base = Pleroma.Web.ActivityPub.Utils.make_json_ld_header()
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
 
     additional =
       Transmogrifier.prepare_object(activity.data)
index 93c9f436c4acb70478dfe9919281c6e3c8662c13..241224b57f1ad65a78097f68c714f94de0577429 100644 (file)
@@ -112,7 +112,8 @@ defmodule Pleroma.Web.ActivityPub.UserView do
       "tag" => emoji_tags,
       # Note: key name is indeed "discoverable" (not an error)
       "discoverable" => user.is_discoverable,
-      "capabilities" => capabilities
+      "capabilities" => capabilities,
+      "alsoKnownAs" => user.also_known_as
     }
     |> Map.merge(maybe_make_image(&User.avatar_url/2, "icon", user))
     |> Map.merge(maybe_make_image(&User.banner_url/2, "image", user))
index 75525104ff98a29788219e930e023dd3d7e147cc..1c7c26d9816b68087bbba50cfb60992e82aab457 100644 (file)
@@ -103,13 +103,15 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
     godmode = params["godmode"] == "true" || params["godmode"] == true
 
     with %User{} = user <- User.get_cached_by_nickname_or_id(nickname, for: admin) do
-      {_, page_size} = page_params(params)
+      {page, page_size} = page_params(params)
 
       activities =
         ActivityPub.fetch_user_activities(user, nil, %{
           limit: page_size,
+          offset: (page - 1) * page_size,
           godmode: godmode,
-          exclude_reblogs: not with_reblogs
+          exclude_reblogs: not with_reblogs,
+          pagination_type: :offset
         })
 
       conn
index 8bac24d3efabdb991e61999147c6eb5b57395abc..ebf90b91b3c68ec6171e0e17d0d95aef9330b516 100644 (file)
@@ -69,6 +69,7 @@ defmodule Pleroma.Web.AdminAPI.AccountView do
 
     %{
       "id" => user.id,
+      "email" => user.email,
       "avatar" => avatar,
       "nickname" => user.nickname,
       "display_name" => display_name,
index 112f9e0e1020b6e4cee4afb9a727ed91e56121d4..3fa778b0a4ff6d5b24f366851d9aa979385663b4 100644 (file)
@@ -21,6 +21,7 @@ defmodule Pleroma.Web.AdminAPI.ModerationLogView do
       |> DateTime.to_unix()
 
     %{
+      id: log_entry.id,
       data: log_entry.data,
       time: time,
       message: ModerationLog.get_log_entry_message(log_entry)
index 5355563704d11a62816b7ec62442e088fa94b2a0..da949e3062cdf41147c2f5e708d2cf9634856cf7 100644 (file)
@@ -19,8 +19,7 @@ defmodule Pleroma.Web.AdminAPI.ReportView do
       reports:
         reports[:items]
         |> Enum.map(&Report.extract_report_info/1)
-        |> Enum.map(&render(__MODULE__, "show.json", &1))
-        |> Enum.reverse(),
+        |> Enum.map(&render(__MODULE__, "show.json", &1)),
       total: reports[:total]
     }
   end
index 280100c3d13edd68383d97394ff4f268fa8acc15..bd3a73c11f6a12ca7de7ae624060ac498d437c4b 100644 (file)
@@ -614,6 +614,12 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
           nullable: true,
           description: "Allows automatically follow moved following accounts"
         },
+        also_known_as: %Schema{
+          type: :array,
+          items: %Schema{type: :string},
+          nullable: true,
+          description: "List of alternate ActivityPub IDs"
+        },
         pleroma_background_image: %Schema{
           type: :string,
           nullable: true,
@@ -644,6 +650,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
         pleroma_settings_store: %{"pleroma-fe" => %{"key" => "val"}},
         skip_thread_containment: false,
         allow_following_move: false,
+        also_known_as: ["https://foo.bar/users/foo"],
         discoverable: false,
         actor_type: "Person"
       }
index 684f6fc92e3287ee61d780344162d2a9674859c1..70437003c3cd82a33a6408b2a4277b9631977275 100644 (file)
@@ -40,6 +40,8 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Account do
       pleroma: %Schema{
         type: :object,
         properties: %{
+          ap_id: %Schema{type: :string},
+          also_known_as: %Schema{type: :array, items: %Schema{type: :string}},
           allow_following_move: %Schema{
             type: :boolean,
             description: "whether the user allows automatically follow moved following accounts"
index e592547911043308b5d841e08d05ac892dcd8c57..87343df752e41d48659d3f03e767c294c51a4dc9 100644 (file)
@@ -142,7 +142,7 @@ defmodule Pleroma.Web.CommonAPI do
     with {_, %Activity{data: %{"object" => _, "type" => "Create"}} = activity} <-
            {:find_activity, Activity.get_by_id(activity_id)},
          {_, %Object{} = object, _} <-
-           {:find_object, Object.normalize(activity, false), activity},
+           {:find_object, Object.normalize(activity, fetch: false), activity},
          true <- User.superuser?(user) || user.ap_id == object.data["actor"],
          {:ok, delete_data, _} <- Builder.delete(user, object.data["id"]),
          {:ok, delete, _} <- Pipeline.common_pipeline(delete_data, local: true) do
@@ -173,7 +173,7 @@ defmodule Pleroma.Web.CommonAPI do
 
   def repeat(id, user, params \\ %{}) do
     with %Activity{data: %{"type" => "Create"}} = activity <- Activity.get_by_id(id),
-         object = %Object{} <- Object.normalize(activity, false),
+         object = %Object{} <- Object.normalize(activity, fetch: false),
          {_, nil} <- {:existing_announce, Utils.get_existing_announce(user.ap_id, object)},
          public = public_announce?(object, params),
          {:ok, announce, _} <- Builder.announce(user, object, public: public),
@@ -191,7 +191,7 @@ defmodule Pleroma.Web.CommonAPI do
   def unrepeat(id, user) do
     with {_, %Activity{data: %{"type" => "Create"}} = activity} <-
            {:find_activity, Activity.get_by_id(id)},
-         %Object{} = note <- Object.normalize(activity, false),
+         %Object{} = note <- Object.normalize(activity, fetch: false),
          %Activity{} = announce <- Utils.get_existing_announce(user.ap_id, note),
          {:ok, undo, _} <- Builder.undo(user, announce),
          {:ok, activity, _} <- Pipeline.common_pipeline(undo, local: true) do
@@ -253,7 +253,7 @@ defmodule Pleroma.Web.CommonAPI do
   def unfavorite(id, user) do
     with {_, %Activity{data: %{"type" => "Create"}} = activity} <-
            {:find_activity, Activity.get_by_id(id)},
-         %Object{} = note <- Object.normalize(activity, false),
+         %Object{} = note <- Object.normalize(activity, fetch: false),
          %Activity{} = like <- Utils.get_existing_like(user.ap_id, note),
          {:ok, undo, _} <- Builder.undo(user, like),
          {:ok, activity, _} <- Pipeline.common_pipeline(undo, local: true) do
@@ -266,7 +266,7 @@ defmodule Pleroma.Web.CommonAPI do
 
   def react_with_emoji(id, user, emoji) do
     with %Activity{} = activity <- Activity.get_by_id(id),
-         object <- Object.normalize(activity),
+         object <- Object.normalize(activity, fetch: false),
          {:ok, emoji_react, _} <- Builder.emoji_react(user, object, emoji),
          {:ok, activity, _} <- Pipeline.common_pipeline(emoji_react, local: true) do
       {:ok, activity}
@@ -377,7 +377,7 @@ defmodule Pleroma.Web.CommonAPI do
   def get_replied_to_visibility(nil), do: nil
 
   def get_replied_to_visibility(activity) do
-    with %Object{} = object <- Object.normalize(activity) do
+    with %Object{} = object <- Object.normalize(activity, fetch: false) do
       Visibility.get_visibility(object)
     end
   end
index 1c74ea7875760355cbfc4baf7c0a58bf7bfb69a2..ddbdb33763d066e68faa2002c3156b92cf70b65a 100644 (file)
@@ -319,7 +319,7 @@ defmodule Pleroma.Web.CommonAPI.Utils do
   defp add_in_reply_to(object, nil), do: object
 
   defp add_in_reply_to(object, in_reply_to) do
-    with %Object{} = in_reply_to_object <- Object.normalize(in_reply_to) do
+    with %Object{} = in_reply_to_object <- Object.normalize(in_reply_to, fetch: false) do
       Map.put(object, "inReplyTo", in_reply_to_object.data["id"])
     else
       _ -> object
@@ -399,7 +399,7 @@ defmodule Pleroma.Web.CommonAPI.Utils do
         %Activity{data: %{"to" => _to, "type" => type} = data} = activity
       )
       when type == "Create" do
-    object = Object.normalize(activity, false)
+    object = Object.normalize(activity, fetch: false)
 
     object_data =
       cond do
index f6b8a5ee15cffc58d539c98e6aaf3473b031257a..f8623d4d6157562e7aa6c0904e98d5d9b03da092 100644 (file)
@@ -31,7 +31,7 @@ defmodule Pleroma.Web.EmbedController do
   end
 
   defp get_counts(%Activity{} = activity) do
-    %Object{data: data} = Object.normalize(activity)
+    %Object{data: data} = Object.normalize(activity, fetch: false)
 
     %{
       likes: Map.get(data, "like_count", 0),
index 30e0a2a55b69228b470ed0a35a8111ff80c6149e..bc0114e26fc980ac235ad387cb1dd4c32773e313 100644 (file)
@@ -23,7 +23,7 @@ defmodule Pleroma.Web.Feed.FeedView do
   def pub_date(%DateTime{} = date), do: Timex.format!(date, "{RFC822}")
 
   def prepare_activity(activity, opts \\ []) do
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
 
     actor =
       if opts[:actor] do
index b4375872b6743ecf725fe60654f74fd05ddccb33..3951d10ac9a2cfb371d4e18706386da55062d37b 100644 (file)
@@ -184,6 +184,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
         :show_role,
         :skip_thread_containment,
         :allow_following_move,
+        :also_known_as,
         :accepts_chat_messages
       ]
       |> Enum.reduce(%{}, fn key, acc ->
@@ -207,6 +208,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
         if bot, do: {:ok, "Service"}, else: {:ok, "Person"}
       end)
       |> Maps.put_if_present(:actor_type, params[:actor_type])
+      |> Maps.put_if_present(:also_known_as, params[:also_known_as])
       # Note: param name is indeed :locked (not an error)
       |> Maps.put_if_present(:is_locked, params[:locked])
       # Note: param name is indeed :discoverable (not an error)
index 9e3a584f0b03e761be36cd716fa2b84010934a58..acca9d3b24a28931186a63f02ef43026f262b642 100644 (file)
@@ -318,7 +318,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
     with true <- Pleroma.Config.get([:instance, :show_reactions]),
          %Activity{} = activity <- Activity.get_by_id_with_object(id),
          {:visible, true} <- {:visible, Visibility.visible_for_user?(activity, user)},
-         %Object{data: %{"likes" => likes}} <- Object.normalize(activity) do
+         %Object{data: %{"likes" => likes}} <- Object.normalize(activity, fetch: false) do
       users =
         User
         |> Ecto.Query.where([u], u.ap_id in ^likes)
@@ -339,7 +339,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
     with %Activity{} = activity <- Activity.get_by_id_with_object(id),
          {:visible, true} <- {:visible, Visibility.visible_for_user?(activity, user)},
          %Object{data: %{"announcements" => announces, "id" => ap_id}} <-
-           Object.normalize(activity) do
+           Object.normalize(activity, fetch: false) do
       announces =
         "Announce"
         |> Activity.Queries.by_type()
index 026ae9458d24a301180a0aa97027fb349fd9b94e..948a05a6dc122ff0c33cdd6f8f637e18f023bfd5 100644 (file)
@@ -265,6 +265,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
       # Pleroma extension
       pleroma: %{
         ap_id: user.ap_id,
+        also_known_as: user.also_known_as,
         confirmation_pending: user.confirmation_pending,
         tags: user.tags,
         hide_followers_count: user.hide_followers_count,
index 5b06a6b51568295b53c970b1e4891b3929218b76..9ec0f311df6d626b36b23e92e7a3ff78a809d7d0 100644 (file)
@@ -139,7 +139,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do
   end
 
   defp put_chat_message(response, activity, reading_user, opts) do
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
     author = User.get_cached_by_ap_id(object.data["actor"])
     chat = Pleroma.Chat.get(reading_user.id, author.ap_id)
     cm_ref = MessageReference.for_chat_and_object(chat, object)
index 2301e21cfaf2d56b760fe35fa733dd2be502eeba..b8a35cd38b9167bcf61915fc1c9716dfcb1da758 100644 (file)
@@ -41,7 +41,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
     activities
     |> Enum.map(fn
       %{data: %{"type" => "Create"}} = activity ->
-        object = Object.normalize(activity)
+        object = Object.normalize(activity, fetch: false)
         object && object.data["inReplyTo"] != "" && object.data["inReplyTo"]
 
       _ ->
@@ -51,7 +51,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
     |> Activity.create_by_object_ap_id_with_object()
     |> Repo.all()
     |> Enum.reduce(%{}, fn activity, acc ->
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
       if object, do: Map.put(acc, object.data["id"], activity), else: acc
     end)
   end
@@ -65,7 +65,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
   defp get_context_id(_), do: nil
 
   defp reblogged?(activity, user) do
-    object = Object.normalize(activity) || %{}
+    object = Object.normalize(activity, fetch: false) || %{}
     present?(user && user.ap_id in (object.data["announcements"] || []))
   end
 
@@ -84,7 +84,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
     parent_activities =
       activities
       |> Enum.filter(&(&1.data["type"] == "Announce" && &1.data["object"]))
-      |> Enum.map(&Object.normalize(&1).data["id"])
+      |> Enum.map(&Object.normalize(&1, fetch: false).data["id"])
       |> Activity.create_by_object_ap_id()
       |> Activity.with_preloaded_object(:left)
       |> Activity.with_preloaded_bookmark(reading_user)
@@ -124,7 +124,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
       ) do
     user = CommonAPI.get_user(activity.data["actor"])
     created_at = Utils.to_masto_date(activity.data["published"])
-    activity_object = Object.normalize(activity)
+    activity_object = Object.normalize(activity, fetch: false)
 
     reblogged_parent_activity =
       if opts[:parent_activities] do
@@ -193,7 +193,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
   end
 
   def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
 
     user = CommonAPI.get_user(activity.data["actor"])
     user_follower_address = user.follower_address
@@ -451,7 +451,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
   end
 
   def get_reply_to(activity, %{replied_to_activities: replied_to_activities}) do
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
 
     with nil <- replied_to_activities[object.data["inReplyTo"]] do
       # If user didn't participate in the thread
@@ -460,7 +460,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
   end
 
   def get_reply_to(%{data: %{"object" => _object}} = activity, _) do
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
 
     if object.data["inReplyTo"] && object.data["inReplyTo"] != "" do
       Activity.get_create_by_object_ap_id(object.data["inReplyTo"])
index 668ae0ea4fde363ba01e4eb24f92380d4e61ae76..ea182d698627da70041f84a5020308e9cf61dd08 100644 (file)
@@ -74,14 +74,14 @@ defmodule Pleroma.Web.OStatus.OStatusController do
       cond do
         format in ["json", "activity+json"] ->
           if activity.local do
-            %{data: %{"id" => redirect_url}} = Object.normalize(activity)
+            %{data: %{"id" => redirect_url}} = Object.normalize(activity, fetch: false)
             redirect(conn, external: redirect_url)
           else
             {:error, :not_found}
           end
 
         activity.data["type"] == "Create" ->
-          %Object{} = object = Object.normalize(activity)
+          %Object{} = object = Object.normalize(activity, fetch: false)
 
           RedirectController.redirector_with_meta(
             conn,
@@ -112,7 +112,7 @@ defmodule Pleroma.Web.OStatus.OStatusController do
     with %Activity{data: %{"type" => "Create"}} = activity <- Activity.get_by_id_with_object(id),
          true <- Visibility.is_public?(activity),
          {_, true} <- {:visible?, Visibility.visible_for_user?(activity, _reading_user = nil)},
-         %Object{} = object <- Object.normalize(activity),
+         %Object{} = object <- Object.normalize(activity, fetch: false),
          %{data: %{"attachment" => [%{"url" => [url | _]} | _]}} <- object,
          true <- String.starts_with?(url["mediaType"], ["audio", "video"]) do
       conn
index bfc0a1f191f55463c8d86ed51a3d69d0af2934a4..1825e216883354d252bed1216940be04c207ed33 100644 (file)
@@ -82,7 +82,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatController do
              media_id: params[:media_id],
              idempotency_key: idempotency_key(conn)
            ),
-         message <- Object.normalize(activity, false),
+         message <- Object.normalize(activity, fetch: false),
          cm_ref <- MessageReference.for_chat_and_object(chat, message) do
       conn
       |> put_view(MessageReferenceView)
index dd9c746dcaf03113546f0688ac9b898dd721f673..dee04f045d920b9f6c180cb0da55b96f55de5a9d 100644 (file)
@@ -29,7 +29,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionController do
     with true <- Pleroma.Config.get([:instance, :show_reactions]),
          %Activity{} = activity <- Activity.get_by_id_with_object(activity_id),
          %Object{data: %{"reactions" => reactions}} when is_list(reactions) <-
-           Object.normalize(activity) do
+           Object.normalize(activity, fetch: false) do
       reactions =
         reactions
         |> filter(params)
index af75876aa184a51e5b57f52503f223da35cb475a..39affe9793abd87ea255f8008569a3de4c9fc9db 100644 (file)
@@ -10,6 +10,7 @@ defmodule Pleroma.Web.PleromaAPI.BackupView do
 
   def render("show.json", %{backup: %Backup{} = backup}) do
     %{
+      id: backup.id,
       content_type: backup.content_type,
       url: download_url(backup),
       file_size: backup.file_size,
index 95bd4c368994a102512481d668b26d4de03c96f7..98b95c72108c86129dd679c73f84bc0a96dc1e60 100644 (file)
@@ -15,7 +15,7 @@ defmodule Pleroma.Web.PleromaAPI.ScrobbleView do
   alias Pleroma.Web.MastodonAPI.AccountView
 
   def render("show.json", %{activity: %Activity{data: %{"type" => "Listen"}} = activity} = opts) do
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
 
     user = CommonAPI.get_user(activity.data["actor"])
     created_at = Utils.to_masto_date(activity.data["published"])
index 402a8bb34c3d4b71f2decde632902601227c7041..94b4c2177d9ae762c5d1491c3c611ce882df95f6 100644 (file)
@@ -87,8 +87,15 @@ defmodule Pleroma.Web.Plugs.UploadedMedia do
   end
 
   defp get_media(conn, {:url, url}, true, _) do
+    proxy_opts = [
+      http: [
+        follow_redirect: true,
+        pool: :upload
+      ]
+    ]
+
     conn
-    |> Pleroma.ReverseProxy.call(url, Pleroma.Config.get([Pleroma.Upload, :proxy_opts], []))
+    |> Pleroma.ReverseProxy.call(url, proxy_opts)
   end
 
   defp get_media(conn, {:url, url}, _, _) do
index 82152dffa1f324adb839ba36fe4443e8a65dd487..a9c46f63ad102793025d0ba7eccc02688e8b1a09 100644 (file)
@@ -32,7 +32,7 @@ defmodule Pleroma.Web.Push.Impl do
     mastodon_type = notification.type
     gcm_api_key = Application.get_env(:web_push_encryption, :gcm_api_key)
     avatar_url = User.avatar_url(actor)
-    object = Object.normalize(activity, false)
+    object = Object.normalize(activity, fetch: false)
     user = User.get_cached_by_id(user_id)
     direct_conversation_id = Activity.direct_conversation_id(activity, user)
 
index 442bf99957a9aa952518f5777bbed9dff806bba4..566fc8c8a91877a52448dba857e3abf49570064e 100644 (file)
@@ -69,7 +69,7 @@ defmodule Pleroma.Web.RichMedia.Helpers do
 
   def fetch_data_for_activity(%Activity{data: %{"type" => "Create"}} = activity) do
     with true <- Config.get([:rich_media, :enabled]),
-         %Object{} = object <- Object.normalize(activity) do
+         %Object{} = object <- Object.normalize(activity, fetch: false) do
       fetch_data_for_object(object)
     else
       _ -> %{}
index bdec0897a6dac228a3916fae3a8630ae770628ea..404cb0473ae3235f21cdd5959ffd72c67407d592 100644 (file)
@@ -122,7 +122,7 @@ defmodule Pleroma.Web.StaticFE.StaticFEController do
   end
 
   defp get_counts(%Activity{} = activity) do
-    %Object{data: data} = Object.normalize(activity)
+    %Object{data: data} = Object.normalize(activity, fetch: false)
 
     %{
       likes: data["like_count"] || 0,
index 7d4a1304a9b381e3f25bfec72acd38398adcc070..1fb8ac1c5b66e8082fb88d009c4aa69732c96399 100644 (file)
@@ -151,7 +151,7 @@ defmodule Pleroma.Web.Streamer do
     recipients = MapSet.new(item.recipients)
     domain_blocks = Pleroma.Web.ActivityPub.MRF.subdomains_regex(user.domain_blocks)
 
-    with parent <- Object.normalize(item) || item,
+    with parent <- Object.normalize(item, fetch: false) || item,
          true <- Enum.all?([blocked_ap_ids, muted_ap_ids], &(item.actor not in &1)),
          true <- item.data["type"] != "Announce" || item.actor not in reblog_muted_ap_ids,
          true <-
index 2e39ae0484bb0edd0a1a8839b91f2654d87cedcd..a109e1accfcaa0287c169f4b367d10451197e50f 100644 (file)
@@ -58,12 +58,16 @@ defmodule Pleroma.Web.WebFinger do
     ] ++ Publisher.gather_webfinger_links(user)
   end
 
+  defp gather_aliases(%User{} = user) do
+    [user.ap_id | user.also_known_as]
+  end
+
   def represent_user(user, "JSON") do
     {:ok, user} = User.ensure_keys_present(user)
 
     %{
       "subject" => "acct:#{user.nickname}@#{Pleroma.Web.Endpoint.host()}",
-      "aliases" => [user.ap_id],
+      "aliases" => gather_aliases(user),
       "links" => gather_links(user)
     }
   end
@@ -71,6 +75,11 @@ defmodule Pleroma.Web.WebFinger do
   def represent_user(user, "XML") do
     {:ok, user} = User.ensure_keys_present(user)
 
+    aliases =
+      user
+      |> gather_aliases()
+      |> Enum.map(&{:Alias, &1})
+
     links =
       gather_links(user)
       |> Enum.map(fn link -> {:Link, link} end)
@@ -79,9 +88,8 @@ defmodule Pleroma.Web.WebFinger do
       :XRD,
       %{xmlns: "http://docs.oasis-open.org/ns/xri/xrd-1.0"},
       [
-        {:Subject, "acct:#{user.nickname}@#{Pleroma.Web.Endpoint.host()}"},
-        {:Alias, user.ap_id}
-      ] ++ links
+        {:Subject, "acct:#{user.nickname}@#{Pleroma.Web.Endpoint.host()}"}
+      ] ++ aliases ++ links
     }
     |> XmlBuilder.to_doc()
   end
diff --git a/mix.exs b/mix.exs
index a596e34ea32b621cefca6fc7c4ba8634315887e9..f26a5391aa48ae35ddbbbfcd8aff3b344a36be6b 100644 (file)
--- a/mix.exs
+++ b/mix.exs
@@ -147,8 +147,8 @@ defmodule Pleroma.Mixfile do
       {:earmark, "1.4.3"},
       {:bbcode_pleroma, "~> 0.2.0"},
       {:crypt,
-       git: "https://github.com/msantos/crypt.git",
-       ref: "f63a705f92c26955977ee62a313012e309a4d77a"},
+       git: "https://git.pleroma.social/pleroma/elixir-libraries/crypt.git",
+       ref: "cf2aa3f11632e8b0634810a15b3e612c7526f6a3"},
       {:cors_plug, "~> 2.0"},
       {:web_push_encryption, "~> 0.3"},
       {:swoosh, "~> 1.0"},
index 32b2e13911d941b61dbc2e2d699bd5b18c61200a..01caf319e471f4cca93b1a69eeeb9a6440ce0eb2 100644 (file)
--- a/mix.lock
+++ b/mix.lock
@@ -22,7 +22,7 @@
   "cowlib": {:hex, :cowlib, "2.9.1", "61a6c7c50cf07fdd24b2f45b89500bb93b6686579b069a89f88cb211e1125c78", [:rebar3], [], "hexpm", "e4175dc240a70d996156160891e1c62238ede1729e45740bdd38064dad476170"},
   "credo": {:hex, :credo, "1.4.1", "16392f1edd2cdb1de9fe4004f5ab0ae612c92e230433968eab00aafd976282fc", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "155f8a2989ad77504de5d8291fa0d41320fdcaa6a1030472e9967f285f8c7692"},
   "crontab": {:hex, :crontab, "1.1.8", "2ce0e74777dfcadb28a1debbea707e58b879e6aa0ffbf9c9bb540887bce43617", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
-  "crypt": {:git, "https://github.com/msantos/crypt.git", "f63a705f92c26955977ee62a313012e309a4d77a", [ref: "f63a705f92c26955977ee62a313012e309a4d77a"]},
+  "crypt": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/crypt.git", "cf2aa3f11632e8b0634810a15b3e612c7526f6a3", [ref: "cf2aa3f11632e8b0634810a15b3e612c7526f6a3"]},
   "custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm", "8df019facc5ec9603e94f7270f1ac73ddf339f56ade76a721eaa57c1493ba463"},
   "db_connection": {:hex, :db_connection, "2.2.2", "3bbca41b199e1598245b716248964926303b5d4609ff065125ce98bcd368939e", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm", "642af240d8a8affb93b4ba5a6fcd2bbcbdc327e1a524b825d383711536f8070c"},
   "decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
diff --git a/priv/static/emoji/dino walking.gif b/priv/static/emoji/dino walking.gif
new file mode 100644 (file)
index 0000000..694a541
Binary files /dev/null and b/priv/static/emoji/dino walking.gif differ
index de8ab27e5451826f610802317262432fc280dfb5..9f898d8f35aeb42fcef676be554369429dc43df3 100644 (file)
@@ -114,7 +114,7 @@ defmodule Mix.Tasks.Pleroma.UserTest do
 
       {:ok, post} = CommonAPI.post(user, %{status: "uguu"})
       {:ok, post2} = CommonAPI.post(user2, %{status: "test"})
-      obj = Object.normalize(post2)
+      obj = Object.normalize(post2, fetch: false)
 
       {:ok, like_object, meta} = Pleroma.Web.ActivityPub.Builder.like(user, obj)
 
@@ -130,7 +130,7 @@ defmodule Mix.Tasks.Pleroma.UserTest do
 
       clear_config([:instance, :federating], true)
 
-      object = Object.normalize(post)
+      object = Object.normalize(post, fetch: false)
       Object.prune(object)
 
       with_mock Pleroma.Web.Federator,
index 105f9f7668d9210494f0ea034c0c862cec99727c..acaa9adb480dc66a6fb90afadd6d276858f62b41 100644 (file)
@@ -25,7 +25,7 @@ defmodule Pleroma.ActivityTest do
 
   test "returns activities by it's objects AP ids" do
     activity = insert(:note_activity)
-    object_data = Object.normalize(activity).data
+    object_data = Object.normalize(activity, fetch: false).data
 
     [found_activity] = Activity.get_all_create_by_object_ap_id(object_data["id"])
 
@@ -34,7 +34,7 @@ defmodule Pleroma.ActivityTest do
 
   test "returns the activity that created an object" do
     activity = insert(:note_activity)
-    object_data = Object.normalize(activity).data
+    object_data = Object.normalize(activity, fetch: false).data
 
     found_activity = Activity.get_create_by_object_ap_id(object_data["id"])
 
index bba8fab0faa60045705232cdc89bd20dd6a2dc79..8033828f082b4a0bacc659c74ff9ea7c84de0900 100644 (file)
@@ -54,7 +54,7 @@ defmodule Pleroma.BBS.HandlerTest do
       )
 
     assert activity.actor == user.ap_id
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
     assert object.data["content"] == "this is a test post"
   end
 
@@ -63,7 +63,7 @@ defmodule Pleroma.BBS.HandlerTest do
     another_user = insert(:user)
 
     {:ok, activity} = CommonAPI.post(another_user, %{status: "this is a test post"})
-    activity_object = Object.normalize(activity)
+    activity_object = Object.normalize(activity, fetch: false)
 
     output =
       capture_io(fn ->
@@ -82,7 +82,7 @@ defmodule Pleroma.BBS.HandlerTest do
 
     assert reply.actor == user.ap_id
 
-    reply_object_data = Object.normalize(reply).data
+    reply_object_data = Object.normalize(reply, fetch: false).data
     assert reply_object_data["content"] == "this is a reply"
     assert reply_object_data["inReplyTo"] == activity_object.data["id"]
   end
index 122b10486f8562ff00f491efbfb8fc22d6feb6d9..917fb2b988348afb3b7fa5e2627e82839c13ba43 100644 (file)
@@ -175,8 +175,8 @@ defmodule Pleroma.Conversation.ParticipationTest do
 
     assert [participation_one, participation_two] = Participation.for_user(user)
 
-    object2 = Pleroma.Object.normalize(activity_two)
-    object3 = Pleroma.Object.normalize(activity_three)
+    object2 = Pleroma.Object.normalize(activity_two, fetch: false)
+    object3 = Pleroma.Object.normalize(activity_three, fetch: false)
 
     user = Repo.get(Pleroma.User, user.id)
 
index 359aa68403a413fc2488227c84d938c71b712e2f..4643140dc9689b3ec82661a7e76dc68f811023f5 100644 (file)
@@ -48,7 +48,7 @@ defmodule Pleroma.ConversationTest do
     user = insert(:user)
     {:ok, activity} = CommonAPI.post(user, %{status: "Hey"})
 
-    object = Pleroma.Object.normalize(activity)
+    object = Pleroma.Object.normalize(activity, fetch: false)
     context = object.data["context"]
 
     conversation = Conversation.get_for_ap_id(context)
@@ -64,7 +64,7 @@ defmodule Pleroma.ConversationTest do
     {:ok, activity} =
       CommonAPI.post(har, %{status: "Hey @#{jafnhar.nickname}", visibility: "direct"})
 
-    object = Pleroma.Object.normalize(activity)
+    object = Pleroma.Object.normalize(activity, fetch: false)
     context = object.data["context"]
 
     conversation =
@@ -86,7 +86,7 @@ defmodule Pleroma.ConversationTest do
         in_reply_to_status_id: activity.id
       })
 
-    object = Pleroma.Object.normalize(activity)
+    object = Pleroma.Object.normalize(activity, fetch: false)
     context = object.data["context"]
 
     conversation_two =
@@ -110,7 +110,7 @@ defmodule Pleroma.ConversationTest do
         in_reply_to_status_id: activity.id
       })
 
-    object = Pleroma.Object.normalize(activity)
+    object = Pleroma.Object.normalize(activity, fetch: false)
     context = object.data["context"]
 
     conversation_three =
index 9737f24588dd4b3a3daf401ef42d4ca3c6eca252..3a926f0777f379b45bae95846c249ffc8daf904a 100644 (file)
@@ -175,7 +175,7 @@ defmodule Pleroma.HTMLTest do
             "I think I just found the best github repo https://github.com/komeiji-satori/Dress"
         })
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
       {:ok, url} = HTML.extract_first_external_url_from_object(object)
       assert url == "https://github.com/komeiji-satori/Dress"
     end
@@ -190,7 +190,7 @@ defmodule Pleroma.HTMLTest do
             "@#{other_user.nickname} install misskey! https://github.com/syuilo/misskey/blob/develop/docs/setup.en.md"
         })
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
       {:ok, url} = HTML.extract_first_external_url_from_object(object)
 
       assert url == "https://github.com/syuilo/misskey/blob/develop/docs/setup.en.md"
@@ -206,7 +206,7 @@ defmodule Pleroma.HTMLTest do
           status: "#cofe https://www.pixiv.net/member_illust.php?mode=medium&illust_id=72255140"
         })
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
       {:ok, url} = HTML.extract_first_external_url_from_object(object)
 
       assert url == "https://www.pixiv.net/member_illust.php?mode=medium&illust_id=72255140"
@@ -222,7 +222,7 @@ defmodule Pleroma.HTMLTest do
           content_type: "text/html"
         })
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
       {:ok, url} = HTML.extract_first_external_url_from_object(object)
 
       assert url == "https://www.pixiv.net/member_illust.php?mode=medium&illust_id=72255140"
@@ -233,7 +233,7 @@ defmodule Pleroma.HTMLTest do
 
       {:ok, activity} = CommonAPI.post(user, %{status: "\"http://cofe.com/?boomer=ok&foo=bar\""})
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       assert {:ok, nil} = HTML.extract_first_external_url_from_object(object)
     end
@@ -247,7 +247,7 @@ defmodule Pleroma.HTMLTest do
             "<a href=\"https://pleroma.gov/media/d24caa3a498e21e0298377a9ca0149a4f4f8b767178aacf837542282e2d94fb1.png?name=image.png\" class=\"attachment\">image.png</a>"
         })
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       assert {:ok, nil} = HTML.extract_first_external_url_from_object(object)
     end
index 5d4e6fb84691cb904aec72f4cafb10777718f92b..fe7f37e7c320ad9d36d6feff6098ab94592e363e 100644 (file)
@@ -256,23 +256,22 @@ defmodule Pleroma.ObjectTest do
   end
 
   describe "normalizer" do
-    test "fetches unknown objects by default" do
-      %Object{} =
-        object = Object.normalize("http://mastodon.example.org/@admin/99541947525187367")
-
-      assert object.data["url"] == "http://mastodon.example.org/@admin/99541947525187367"
+    @url "http://mastodon.example.org/@admin/99541947525187367"
+    test "does not fetch unknown objects by default" do
+      assert nil == Object.normalize(@url)
     end
 
-    test "fetches unknown objects when fetch_remote is explicitly true" do
-      %Object{} =
-        object = Object.normalize("http://mastodon.example.org/@admin/99541947525187367", true)
+    test "fetches unknown objects when fetch is explicitly true" do
+      %Object{} = object = Object.normalize(@url, fetch: true)
 
-      assert object.data["url"] == "http://mastodon.example.org/@admin/99541947525187367"
+      assert object.data["url"] == @url
     end
 
-    test "does not fetch unknown objects when fetch_remote is false" do
+    test "does not fetch unknown objects when fetch is false" do
       assert is_nil(
-               Object.normalize("http://mastodon.example.org/@admin/99541947525187367", false)
+               Object.normalize(@url,
+                 fetch: false
+               )
              )
     end
   end
@@ -310,7 +309,10 @@ defmodule Pleroma.ObjectTest do
       mock_modified: mock_modified
     } do
       %Object{} =
-        object = Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d")
+        object =
+        Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d",
+          fetch: true
+        )
 
       Object.set_cache(object)
 
@@ -332,7 +334,10 @@ defmodule Pleroma.ObjectTest do
 
     test "returns the old object if refetch fails", %{mock_modified: mock_modified} do
       %Object{} =
-        object = Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d")
+        object =
+        Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d",
+          fetch: true
+        )
 
       Object.set_cache(object)
 
@@ -355,7 +360,10 @@ defmodule Pleroma.ObjectTest do
       mock_modified: mock_modified
     } do
       %Object{} =
-        object = Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d")
+        object =
+        Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d",
+          fetch: true
+        )
 
       Object.set_cache(object)
 
@@ -377,7 +385,10 @@ defmodule Pleroma.ObjectTest do
 
     test "preserves internal fields on refetch", %{mock_modified: mock_modified} do
       %Object{} =
-        object = Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d")
+        object =
+        Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d",
+          fetch: true
+        )
 
       Object.set_cache(object)
 
index fe26d6e4d869c2db0f479a754988b055f7152091..0b744fc1bf549d9ae7e5d7d88366d0e57b5a68f6 100644 (file)
@@ -28,8 +28,10 @@ defmodule Pleroma.User.WelcomeChatMessageTest do
       {:ok, %Pleroma.Activity{} = activity} = WelcomeChatMessage.post_message(user)
 
       assert user.ap_id in activity.recipients
-      assert Pleroma.Object.normalize(activity).data["type"] == "ChatMessage"
-      assert Pleroma.Object.normalize(activity).data["content"] == "Hello, welcome to Blob/Cat!"
+      assert Pleroma.Object.normalize(activity, fetch: false).data["type"] == "ChatMessage"
+
+      assert Pleroma.Object.normalize(activity, fetch: false).data["content"] ==
+               "Hello, welcome to Blob/Cat!"
     end
   end
 end
index 3cd6f5cb78e9254c61353987f5cb8a616493a543..a1779ddecb1c9b994dc14965abe7c5c095691383 100644 (file)
@@ -28,7 +28,9 @@ defmodule Pleroma.User.WelcomeMessageTest do
       {:ok, %Pleroma.Activity{} = activity} = WelcomeMessage.post_message(user)
       assert user.ap_id in activity.recipients
       assert activity.data["directMessage"] == true
-      assert Pleroma.Object.normalize(activity).data["content"] =~ "Hello. Welcome to Pleroma"
+
+      assert Pleroma.Object.normalize(activity, fetch: false).data["content"] =~
+               "Hello. Welcome to Pleroma"
     end
   end
 end
index 40bbcad0bfb88ad1090da955d098851dced1ebfb..f0f5d60710017d26a91212b9d6512b7b9e64062a 100644 (file)
@@ -438,7 +438,7 @@ defmodule Pleroma.UserTest do
 
       activity = Repo.one(Pleroma.Activity)
       assert registered_user.ap_id in activity.recipients
-      assert Object.normalize(activity).data["content"] =~ "direct message"
+      assert Object.normalize(activity, fetch: false).data["content"] =~ "direct message"
       assert activity.actor == welcome_user.ap_id
     end
 
@@ -454,7 +454,7 @@ defmodule Pleroma.UserTest do
 
       activity = Repo.one(Pleroma.Activity)
       assert registered_user.ap_id in activity.recipients
-      assert Object.normalize(activity).data["content"] =~ "chat message"
+      assert Object.normalize(activity, fetch: false).data["content"] =~ "chat message"
       assert activity.actor == welcome_user.ap_id
     end
 
@@ -493,7 +493,7 @@ defmodule Pleroma.UserTest do
 
       activity = Repo.one(Pleroma.Activity)
       assert registered_user.ap_id in activity.recipients
-      assert Object.normalize(activity).data["content"] =~ "chat message"
+      assert Object.normalize(activity, fetch: false).data["content"] =~ "chat message"
       assert activity.actor == welcome_user.ap_id
     end
 
index 0063d048298b8f6a15d3d738fbbff7125f21d492..03aed794f52926f398526dce31ed27e92e8ce537 100644 (file)
@@ -219,7 +219,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
 
       assert Pleroma.Web.ActivityPub.Visibility.is_local_public?(post)
 
-      object = Object.normalize(post, false)
+      object = Object.normalize(post, fetch: false)
       uuid = String.split(object.data["id"], "/") |> List.last()
 
       conn =
@@ -712,7 +712,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
 
     test "it returns a note activity in a collection", %{conn: conn} do
       note_activity = insert(:direct_note_activity)
-      note_object = Object.normalize(note_activity)
+      note_object = Object.normalize(note_activity, fetch: false)
       user = User.get_cached_by_ap_id(hd(note_activity.data["to"]))
 
       conn =
@@ -999,7 +999,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
 
     test "it returns a note activity in a collection", %{conn: conn} do
       note_activity = insert(:note_activity)
-      note_object = Object.normalize(note_activity)
+      note_object = Object.normalize(note_activity, fetch: false)
       user = User.get_cached_by_ap_id(note_activity.data["actor"])
 
       conn =
@@ -1073,7 +1073,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
 
       assert Activity.get_by_ap_id(result["id"])
       assert result["object"]
-      assert %Object{data: object} = Object.normalize(result["object"])
+      assert %Object{data: object} = Object.normalize(result["object"], fetch: false)
       assert object["content"] == activity["object"]["content"]
     end
 
@@ -1109,7 +1109,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
 
       assert Activity.get_by_ap_id(response["id"])
       assert response["object"]
-      assert %Object{data: response_object} = Object.normalize(response["object"])
+      assert %Object{data: response_object} = Object.normalize(response["object"], fetch: false)
       assert response_object["sensitive"] == true
       assert response_object["content"] == activity["object"]["content"]
 
@@ -1137,7 +1137,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
 
     test "it erects a tombstone when receiving a delete activity", %{conn: conn} do
       note_activity = insert(:note_activity)
-      note_object = Object.normalize(note_activity)
+      note_object = Object.normalize(note_activity, fetch: false)
       user = User.get_cached_by_ap_id(note_activity.data["actor"])
 
       data = %{
@@ -1162,7 +1162,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
 
     test "it rejects delete activity of object from other actor", %{conn: conn} do
       note_activity = insert(:note_activity)
-      note_object = Object.normalize(note_activity)
+      note_object = Object.normalize(note_activity, fetch: false)
       user = insert(:user)
 
       data = %{
@@ -1183,7 +1183,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
 
     test "it increases like count when receiving a like action", %{conn: conn} do
       note_activity = insert(:note_activity)
-      note_object = Object.normalize(note_activity)
+      note_object = Object.normalize(note_activity, fetch: false)
       user = User.get_cached_by_ap_id(note_activity.data["actor"])
 
       data = %{
@@ -1240,7 +1240,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
       assert cirno_outbox["attributedTo"] == nil
       assert cirno_outbox["actor"] == cirno.ap_id
 
-      assert cirno_object = Object.normalize(cirno_outbox["object"])
+      assert cirno_object = Object.normalize(cirno_outbox["object"], fetch: false)
       assert cirno_object.data["actor"] == cirno.ap_id
       assert cirno_object.data["attributedTo"] == cirno.ap_id
     end
@@ -1503,7 +1503,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
     test "it tracks a signed object fetch", %{conn: conn} do
       user = insert(:user, local: false)
       activity = insert(:note_activity)
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       object_path = String.trim_leading(object.data["id"], Pleroma.Web.Endpoint.url())
 
@@ -1519,7 +1519,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
     test "it tracks a signed activity fetch", %{conn: conn} do
       user = insert(:user, local: false)
       activity = insert(:note_activity)
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       activity_path = String.trim_leading(activity.data["id"], Pleroma.Web.Endpoint.url())
 
@@ -1536,7 +1536,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
       user = insert(:user, local: false)
       other_user = insert(:user, local: false)
       activity = insert(:note_activity)
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       object_path = String.trim_leading(object.data["id"], Pleroma.Web.Endpoint.url())
 
@@ -1560,7 +1560,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
       user = insert(:user, local: false)
       other_user = insert(:user, local: false)
       activity = insert(:note_activity)
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       activity_path = String.trim_leading(activity.data["id"], Pleroma.Web.Endpoint.url())
 
@@ -1650,7 +1650,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
       assert activity_response["actor"] == user.ap_id
 
       assert %Object{data: %{"attachment" => [attachment]}} =
-               Object.normalize(activity_response["object"])
+               Object.normalize(activity_response["object"], fetch: false)
 
       assert attachment["type"] == "Document"
       assert attachment["name"] == desc
index 9eb7ae86b138a0c40b949174f196a557b784fc2c..0d30ba20bebdca317763d74a89cc5a4d899a24fb 100644 (file)
@@ -321,7 +321,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
       }
 
       {:ok, %Activity{} = activity} = ActivityPub.insert(data)
-      object = Pleroma.Object.normalize(activity)
+      object = Pleroma.Object.normalize(activity, fetch: false)
 
       assert is_binary(activity.data["context"])
       assert is_binary(object.data["context"])
@@ -344,7 +344,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
       }
 
       {:ok, %Activity{} = activity} = ActivityPub.insert(data)
-      assert object = Object.normalize(activity)
+      assert object = Object.normalize(activity, fetch: false)
       assert is_binary(object.data["id"])
     end
   end
@@ -678,7 +678,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
 
     {:ok, activity_two} = CommonAPI.post(blockee, %{status: "hey! @#{friend.nickname}"})
 
-    assert object = Pleroma.Object.normalize(activity_two)
+    assert object = Pleroma.Object.normalize(activity_two, fetch: false)
 
     data = %{
       "actor" => friend.ap_id,
index 9613dea9bf03a11a54fb5348a3e102ec6418d9f8..da60ac84408810fcae5a3f7e7b838cf2ad03523c 100644 (file)
@@ -18,7 +18,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidationTest do
       announcer = insert(:user)
       {:ok, post_activity} = CommonAPI.post(user, %{status: "uguu"})
 
-      object = Object.normalize(post_activity, false)
+      object = Object.normalize(post_activity, fetch: false)
       {:ok, valid_announce, []} = Builder.announce(announcer, object)
 
       %{
@@ -81,7 +81,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidationTest do
       {:ok, post_activity} =
         CommonAPI.post(user, %{status: "a secret post", visibility: "private"})
 
-      object = Object.normalize(post_activity, false)
+      object = Object.normalize(post_activity, fetch: false)
 
       # Another user can't announce it
       {:ok, announce, []} = Builder.announce(announcer, object, public: false)
index d7e29922443163b0e5c4d1031e302f4e4f49c26a..941a8a3e350d1606bd0b2f94f29866ca13e950e9 100644 (file)
@@ -17,7 +17,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ChatValidationTest do
       user = insert(:user)
       recipient = insert(:user)
       {:ok, activity} = CommonAPI.post_chat_message(user, recipient, "hey")
-      object = Object.normalize(activity, false)
+      object = Object.normalize(activity, fetch: false)
 
       {:ok, create_data, _} = Builder.create(user, object.data, [recipient.ap_id])
 
index 3503d25b22ce906116d91e70f8bd7065abee4030..6d15e1640cf82164eb43be47f40f22faedc4f909 100644 (file)
@@ -322,7 +322,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
       actor = insert(:user)
 
       note_activity = insert(:note_activity, user: actor)
-      object = Object.normalize(note_activity)
+      object = Object.normalize(note_activity, fetch: false)
 
       activity_path = String.trim_leading(note_activity.data["id"], Pleroma.Web.Endpoint.url())
       object_path = String.trim_leading(object.data["id"], Pleroma.Web.Endpoint.url())
diff --git a/test/pleroma/web/activity_pub/side_effects/delete_test.exs b/test/pleroma/web/activity_pub/side_effects/delete_test.exs
new file mode 100644 (file)
index 0000000..cb11f93
--- /dev/null
@@ -0,0 +1,147 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.SideEffects.DeleteTest do
+  use Oban.Testing, repo: Pleroma.Repo
+  use Pleroma.DataCase, async: true
+
+  alias Pleroma.Activity
+  alias Pleroma.Object
+  alias Pleroma.Repo
+  alias Pleroma.Tests.ObanHelpers
+  alias Pleroma.User
+  alias Pleroma.Web.ActivityPub.ActivityPub
+  alias Pleroma.Web.ActivityPub.Builder
+  alias Pleroma.Web.ActivityPub.SideEffects
+  alias Pleroma.Web.CommonAPI
+
+  alias Pleroma.LoggerMock
+  alias Pleroma.Web.ActivityPub.ActivityPubMock
+
+  import Mox
+  import Pleroma.Factory
+
+  describe "user deletion" do
+    setup do
+      user = insert(:user)
+
+      {:ok, delete_user_data, _meta} = Builder.delete(user, user.ap_id)
+      {:ok, delete_user, _meta} = ActivityPub.persist(delete_user_data, local: true)
+
+      %{
+        user: user,
+        delete_user: delete_user
+      }
+    end
+
+    test "it handles user deletions", %{delete_user: delete, user: user} do
+      {:ok, _delete, _} = SideEffects.handle(delete)
+      ObanHelpers.perform_all()
+
+      assert User.get_cached_by_ap_id(user.ap_id).deactivated
+    end
+  end
+
+  describe "object deletion" do
+    setup do
+      user = insert(:user)
+      other_user = insert(:user)
+
+      {:ok, op} = CommonAPI.post(other_user, %{status: "big oof"})
+      {:ok, post} = CommonAPI.post(user, %{status: "hey", in_reply_to_id: op})
+      {:ok, favorite} = CommonAPI.favorite(user, post.id)
+      object = Object.normalize(post, fetch: false)
+      {:ok, delete_data, _meta} = Builder.delete(user, object.data["id"])
+      {:ok, delete, _meta} = ActivityPub.persist(delete_data, local: true)
+
+      %{
+        user: user,
+        delete: delete,
+        post: post,
+        object: object,
+        op: op,
+        favorite: favorite
+      }
+    end
+
+    test "it handles object deletions", %{
+      delete: delete,
+      post: post,
+      object: object,
+      user: user,
+      op: op,
+      favorite: favorite
+    } do
+      object_id = object.id
+      user_id = user.id
+
+      ActivityPubMock
+      |> expect(:stream_out, fn ^delete -> nil end)
+      |> expect(:stream_out_participations, fn %Object{id: ^object_id}, %User{id: ^user_id} ->
+        nil
+      end)
+
+      {:ok, _delete, _} = SideEffects.handle(delete)
+      user = User.get_cached_by_ap_id(object.data["actor"])
+
+      object = Object.get_by_id(object.id)
+      assert object.data["type"] == "Tombstone"
+      refute Activity.get_by_id(post.id)
+      refute Activity.get_by_id(favorite.id)
+
+      user = User.get_by_id(user.id)
+      assert user.note_count == 0
+
+      object = Object.normalize(op.data["object"], fetch: false)
+
+      assert object.data["repliesCount"] == 0
+    end
+
+    test "it handles object deletions when the object itself has been pruned", %{
+      delete: delete,
+      post: post,
+      object: object,
+      user: user,
+      op: op
+    } do
+      object_id = object.id
+      user_id = user.id
+
+      ActivityPubMock
+      |> expect(:stream_out, fn ^delete -> nil end)
+      |> expect(:stream_out_participations, fn %Object{id: ^object_id}, %User{id: ^user_id} ->
+        nil
+      end)
+
+      {:ok, _delete, _} = SideEffects.handle(delete)
+      user = User.get_cached_by_ap_id(object.data["actor"])
+
+      object = Object.get_by_id(object.id)
+      assert object.data["type"] == "Tombstone"
+      refute Activity.get_by_id(post.id)
+
+      user = User.get_by_id(user.id)
+      assert user.note_count == 0
+
+      object = Object.normalize(op.data["object"], fetch: false)
+
+      assert object.data["repliesCount"] == 0
+    end
+
+    test "it logs issues with objects deletion", %{
+      delete: delete,
+      object: object
+    } do
+      {:ok, _object} =
+        object
+        |> Object.change(%{data: Map.delete(object.data, "actor")})
+        |> Repo.update()
+
+      LoggerMock
+      |> expect(:error, fn str -> assert str =~ "The object doesn't have an actor" end)
+
+      {:error, :no_object_actor} = SideEffects.handle(delete)
+    end
+  end
+end
index 297fc0b84d1b2a8bea04b36618bd280856fac93c..50af7a5076523f586e1a40b01b389cd1cd68950b 100644 (file)
@@ -19,7 +19,6 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
   alias Pleroma.Web.ActivityPub.SideEffects
   alias Pleroma.Web.CommonAPI
 
-  import ExUnit.CaptureLog
   import Mock
   import Pleroma.Factory
 
@@ -131,115 +130,6 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
     end
   end
 
-  describe "delete objects" do
-    setup do
-      user = insert(:user)
-      other_user = insert(:user)
-
-      {:ok, op} = CommonAPI.post(other_user, %{status: "big oof"})
-      {:ok, post} = CommonAPI.post(user, %{status: "hey", in_reply_to_id: op})
-      {:ok, favorite} = CommonAPI.favorite(user, post.id)
-      object = Object.normalize(post)
-      {:ok, delete_data, _meta} = Builder.delete(user, object.data["id"])
-      {:ok, delete_user_data, _meta} = Builder.delete(user, user.ap_id)
-      {:ok, delete, _meta} = ActivityPub.persist(delete_data, local: true)
-      {:ok, delete_user, _meta} = ActivityPub.persist(delete_user_data, local: true)
-
-      %{
-        user: user,
-        delete: delete,
-        post: post,
-        object: object,
-        delete_user: delete_user,
-        op: op,
-        favorite: favorite
-      }
-    end
-
-    test "it handles object deletions", %{
-      delete: delete,
-      post: post,
-      object: object,
-      user: user,
-      op: op,
-      favorite: favorite
-    } do
-      with_mock Pleroma.Web.ActivityPub.ActivityPub, [:passthrough],
-        stream_out: fn _ -> nil end,
-        stream_out_participations: fn _, _ -> nil end do
-        {:ok, delete, _} = SideEffects.handle(delete)
-        user = User.get_cached_by_ap_id(object.data["actor"])
-
-        assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out(delete))
-        assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out_participations(object, user))
-      end
-
-      object = Object.get_by_id(object.id)
-      assert object.data["type"] == "Tombstone"
-      refute Activity.get_by_id(post.id)
-      refute Activity.get_by_id(favorite.id)
-
-      user = User.get_by_id(user.id)
-      assert user.note_count == 0
-
-      object = Object.normalize(op.data["object"], false)
-
-      assert object.data["repliesCount"] == 0
-    end
-
-    test "it handles object deletions when the object itself has been pruned", %{
-      delete: delete,
-      post: post,
-      object: object,
-      user: user,
-      op: op
-    } do
-      with_mock Pleroma.Web.ActivityPub.ActivityPub, [:passthrough],
-        stream_out: fn _ -> nil end,
-        stream_out_participations: fn _, _ -> nil end do
-        {:ok, delete, _} = SideEffects.handle(delete)
-        user = User.get_cached_by_ap_id(object.data["actor"])
-
-        assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out(delete))
-        assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out_participations(object, user))
-      end
-
-      object = Object.get_by_id(object.id)
-      assert object.data["type"] == "Tombstone"
-      refute Activity.get_by_id(post.id)
-
-      user = User.get_by_id(user.id)
-      assert user.note_count == 0
-
-      object = Object.normalize(op.data["object"], false)
-
-      assert object.data["repliesCount"] == 0
-    end
-
-    test "it handles user deletions", %{delete_user: delete, user: user} do
-      {:ok, _delete, _} = SideEffects.handle(delete)
-      ObanHelpers.perform_all()
-
-      assert User.get_cached_by_ap_id(user.ap_id).deactivated
-    end
-
-    test "it logs issues with objects deletion", %{
-      delete: delete,
-      object: object
-    } do
-      {:ok, object} =
-        object
-        |> Object.change(%{data: Map.delete(object.data, "actor")})
-        |> Repo.update()
-
-      Object.invalid_object_cache(object)
-
-      assert capture_log(fn ->
-               {:error, :no_object_actor} = SideEffects.handle(delete)
-             end) =~ "object doesn't have an actor"
-    end
-  end
-
   describe "EmojiReact objects" do
     setup do
       poster = insert(:user)
index c06bbc5e96113c016cbb914760da25367be5f013..6ec7e1a0aea23995296fedb1ce54d54a83a3ebaf 100644 (file)
@@ -130,7 +130,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AnnounceHandlingTest do
     assert data["id"] ==
              "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity"
 
-    object = Object.normalize(data["object"])
+    object = Object.normalize(data["object"], fetch: false)
 
     assert object.data["id"] == "http://mastodon.example.org/@admin/99541947525187368"
     assert object.data["content"] == "this is a private toot"
@@ -158,7 +158,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AnnounceHandlingTest do
     data =
       File.read!("test/fixtures/mastodon-announce.json")
       |> Jason.decode!()
-      |> Map.put("object", Object.normalize(activity).data["id"])
+      |> Map.put("object", Object.normalize(activity, fetch: false).data["id"])
       |> Map.put("to", ["http://mastodon.example.org/users/admin/followers"])
       |> Map.put("cc", [])
 
index a1c2ba28a69a9bc6a9b627ed84511ea8e5f2375d..c6483ccafa0bff4393a07b59d8d2eb0b15d4dbf4 100644 (file)
@@ -26,7 +26,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AnswerHandlingTest do
         poll: %{options: ["suya", "suya.", "suya.."], expires_in: 10}
       })
 
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
     assert object.data["repliesCount"] == nil
 
     data =
@@ -37,7 +37,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AnswerHandlingTest do
       |> Kernel.put_in(["object", "to"], user.ap_id)
 
     {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
-    answer_object = Object.normalize(activity)
+    answer_object = Object.normalize(activity, fetch: false)
     assert answer_object.data["type"] == "Answer"
     assert answer_object.data["inReplyTo"] == object.data["id"]
 
@@ -62,7 +62,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AnswerHandlingTest do
         poll: %{options: ["suya", "suya.", "suya.."], expires_in: 10}
       })
 
-    poll_object = Object.normalize(poll_activity)
+    poll_object = Object.normalize(poll_activity, fetch: false)
     # TODO: Replace with CommonAPI vote creation when implemented
     data =
       File.read!("test/fixtures/mastodon-vote.json")
index b0ae804c50dccd41b42602bc1632a977e0d09f8b..26216f7fc6bf6499625d96969b30310a49a098b4 100644 (file)
@@ -25,7 +25,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.ArticleHandlingTest do
 
     {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
 
-    object = Object.normalize(data["object"])
+    object = Object.normalize(data["object"], fetch: false)
 
     assert object.data["name"] == "The end is near: Mastodon plans to drop OStatus support"
 
@@ -75,7 +75,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.ArticleHandlingTest do
     data = File.read!("test/fixtures/prismo-url-map.json") |> Jason.decode!()
 
     {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-    object = Object.normalize(data["object"])
+    object = Object.normalize(data["object"], fetch: false)
 
     assert object.data["url"] == "https://prismo.news/posts/83"
   end
index 7a2ac5d4dcdac1f95da1f56aade18b8e98e3a0aa..ac80d0ddd6f5874d5b45c173e892681fab01758f 100644 (file)
@@ -35,7 +35,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AudioHandlingTest do
 
     {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
 
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
 
     assert object.data["title"] == "lain radio episode 1"
     assert object.data["artist"] == "lain"
@@ -57,7 +57,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AudioHandlingTest do
 
     {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
 
-    assert object = Object.normalize(activity, false)
+    assert object = Object.normalize(activity, fetch: false)
 
     assert object.data["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
 
index 1f9e73ff89af821c89d83f269b00fdaef78c33d3..6dd5088948177653abde6d90a34f4f5ce9059376 100644 (file)
@@ -40,7 +40,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.DeleteHandlingTest do
     assert actor == deleting_user.ap_id
 
     # Objects are replaced by a tombstone object.
-    object = Object.normalize(activity.data["object"])
+    object = Object.normalize(activity.data["object"], fetch: false)
     assert object.data["type"] == "Tombstone"
   end
 
@@ -48,7 +48,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.DeleteHandlingTest do
     activity = insert(:note_activity)
 
     {:ok, object} =
-      Object.normalize(activity.data["object"])
+      Object.normalize(activity.data["object"], fetch: false)
       |> Repo.delete()
 
     # TODO: mock cachex
index b4a006aec7f75048b26d17b64a184f90fb2b5837..b61e5013a1044d12816cd45281a4c86cd7c0e348 100644 (file)
@@ -28,7 +28,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
       data = File.read!("test/fixtures/kroeg-array-less-emoji.json") |> Jason.decode!()
 
       {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-      object = Object.normalize(data["object"])
+      object = Object.normalize(data["object"], fetch: false)
 
       assert object.data["emoji"] == %{
                "icon_e_smile" => "https://puckipedia.com/forum/images/smilies/icon_e_smile.png"
@@ -37,7 +37,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
       data = File.read!("test/fixtures/kroeg-array-less-hashtag.json") |> Jason.decode!()
 
       {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-      object = Object.normalize(data["object"])
+      object = Object.normalize(data["object"], fetch: false)
 
       assert "test" in object.data["tag"]
     end
@@ -66,7 +66,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
       assert data["to"] == []
       assert data["cc"] == to
 
-      object_data = Object.normalize(activity).data
+      object_data = Object.normalize(activity, fetch: false).data
 
       assert object_data["to"] == []
       assert object_data["cc"] == to
@@ -78,7 +78,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
       data =
         File.read!("test/fixtures/mastodon-post-activity.json")
         |> Jason.decode!()
-        |> Map.put("object", Object.normalize(activity).data)
+        |> Map.put("object", Object.normalize(activity, fetch: false).data)
 
       {:ok, returned_activity} = Transmogrifier.handle_incoming(data)
 
@@ -97,7 +97,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
 
       data = Map.put(data, "object", object)
       {:ok, returned_activity} = Transmogrifier.handle_incoming(data)
-      returned_object = Object.normalize(returned_activity, false)
+      returned_object = Object.normalize(returned_activity, fetch: false)
 
       assert %Activity{} =
                Activity.get_create_by_object_ap_id(
@@ -123,7 +123,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
         allowed_thread_distance?: fn _ -> false end do
         {:ok, returned_activity} = Transmogrifier.handle_incoming(data)
 
-        returned_object = Object.normalize(returned_activity, false)
+        returned_object = Object.normalize(returned_activity, fetch: false)
 
         refute Activity.get_create_by_object_ap_id(
                  "tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment"
@@ -179,7 +179,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
 
       assert data["actor"] == "http://mastodon.example.org/users/admin"
 
-      object_data = Object.normalize(data["object"]).data
+      object_data = Object.normalize(data["object"], fetch: false).data
 
       assert object_data["id"] ==
                "http://mastodon.example.org/users/admin/statuses/99512778738411822"
@@ -209,7 +209,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
 
       {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
 
-      object_data = Object.normalize(data["object"], false).data
+      object_data = Object.normalize(data["object"], fetch: false).data
 
       assert object_data["sensitive"] == true
     end
@@ -218,7 +218,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
       data = File.read!("test/fixtures/mastodon-post-activity-hashtag.json") |> Jason.decode!()
 
       {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-      object = Object.normalize(data["object"])
+      object = Object.normalize(data["object"], fetch: false)
 
       assert Enum.at(object.data["tag"], 2) == "moo"
     end
@@ -227,7 +227,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
       data = File.read!("test/fixtures/mastodon-post-activity-contentmap.json") |> Jason.decode!()
 
       {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-      object = Object.normalize(data["object"])
+      object = Object.normalize(data["object"], fetch: false)
 
       assert object.data["content"] ==
                "<p><span class=\"h-card\"><a href=\"http://localtesting.pleroma.lol/users/lain\" class=\"u-url mention\">@<span>lain</span></a></span></p>"
@@ -237,7 +237,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
       data = File.read!("test/fixtures/kroeg-post-activity.json") |> Jason.decode!()
 
       {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-      object = Object.normalize(data["object"])
+      object = Object.normalize(data["object"], fetch: false)
 
       assert object.data["content"] ==
                "<p>henlo from my Psion netBook</p><p>message sent from my Psion netBook</p>"
@@ -725,7 +725,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
           in_reply_to_status_id: id1
         })
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
       replies_uris = Enum.map([self_reply1, self_reply2], fn a -> a.object.data["id"] end)
 
       assert %{"type" => "Collection", "items" => ^replies_uris} =
index 47f92cf4df59c6b177fc76f31b8c0a498fe0aac9..ae470f984cd9336403dd173ed6528237b5ca5183 100644 (file)
@@ -22,7 +22,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.QuestionHandlingTest do
 
     {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
 
-    object = Object.normalize(activity, false)
+    object = Object.normalize(activity, fetch: false)
 
     assert object.data["url"] == "https://mastodon.sdf.org/@rinpatch/102070944809637304"
 
@@ -65,7 +65,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.QuestionHandlingTest do
 
     {:ok, reply_activity} = CommonAPI.post(user, %{status: "hewwo", in_reply_to_id: activity.id})
 
-    reply_object = Object.normalize(reply_activity, false)
+    reply_object = Object.normalize(reply_activity, fetch: false)
 
     assert reply_object.data["context"] == object.data["context"]
     assert reply_object.data["context_id"] == object.data["context_id"]
@@ -101,7 +101,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.QuestionHandlingTest do
       |> Kernel.put_in(["object", "oneOf"], options)
 
     {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
-    object = Object.normalize(activity, false)
+    object = Object.normalize(activity, fetch: false)
 
     assert Enum.sort(object.data["oneOf"]) == Enum.sort(options)
   end
@@ -147,7 +147,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.QuestionHandlingTest do
       |> Kernel.put_in(["object", "tag"], tag)
 
     {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
-    object = Object.normalize(activity, false)
+    object = Object.normalize(activity, fetch: false)
 
     assert object.data["oneOf"] == options
 
index 57411fafacd2f6491b7c64817b5c81909dd2dd5d..be4ac4c13e5668e4fca736281e4d828bdf88d10d 100644 (file)
@@ -24,7 +24,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.VideoHandlingTest do
 
     {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
 
-    assert object = Object.normalize(activity, false)
+    assert object = Object.normalize(activity, fetch: false)
 
     assert object.data["content"] == nil
   end
@@ -34,7 +34,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.VideoHandlingTest do
 
     {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
 
-    assert object = Object.normalize(activity, false)
+    assert object = Object.normalize(activity, fetch: false)
 
     assert object.data["content"] ==
              "<p>Après avoir mené avec un certain succès la campagne « Dégooglisons Internet » en 2014, l’association Framasoft annonce fin 2019 arrêter progressivement un certain nombre de ses services alternatifs aux GAFAM. Pourquoi ?</p><p>Transcription par @aprilorg ici : <a href=\"https://www.april.org/deframasoftisons-internet-pierre-yves-gosset-framasoft\">https://www.april.org/deframasoftisons-internet-pierre-yves-gosset-framasoft</a></p>"
@@ -70,7 +70,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.VideoHandlingTest do
 
     {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
 
-    assert object = Object.normalize(activity, false)
+    assert object = Object.normalize(activity, fetch: false)
 
     assert object.data["attachment"] == [
              %{
index 66ea7664aff340a9135158e9cc9be64e853ded31..c32ea9ae41b20512699cb78ee5f01a09535bfc81 100644 (file)
@@ -56,7 +56,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       other_user = insert(:user)
 
       {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       note_obj = %{
         "type" => "Note",
@@ -281,6 +281,21 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
 
       {:ok, _modified} = Transmogrifier.prepare_outgoing(activity.data)
     end
+
+    test "custom emoji urls are URI encoded" do
+      # :dinosaur: filename has a space -> dino walking.gif
+      user = insert(:user)
+
+      {:ok, activity} = CommonAPI.post(user, %{status: "everybody do the dinosaur :dinosaur:"})
+
+      {:ok, prepared} = Transmogrifier.prepare_outgoing(activity.data)
+
+      assert length(prepared["object"]["tag"]) == 1
+
+      url = prepared["object"]["tag"] |> List.first() |> Map.get("icon") |> Map.get("url")
+
+      assert url == "http://localhost:4001/emoji/dino%20walking.gif"
+    end
   end
 
   describe "user upgrade" do
index 2263b6091536f24b5c59d923d32f1a1067f11e87..83668caa4c676e05e82a0606f4d4a6c3963bea33 100644 (file)
@@ -165,7 +165,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
           }
         })
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
       {:ok, votes, object} = CommonAPI.vote(other_user, object, [0, 1])
       assert Enum.sort(Utils.get_existing_votes(other_user.ap_id, object)) == Enum.sort(votes)
     end
@@ -183,7 +183,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
           }
         })
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
       {:ok, [vote], object} = CommonAPI.vote(other_user, object, [0])
       {:ok, _activity} = CommonAPI.favorite(user, activity.id)
       [fetched_vote] = Utils.get_existing_votes(other_user.ap_id, object)
@@ -242,7 +242,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
     test "updates likes" do
       user = insert(:user)
       activity = insert(:note_activity)
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       assert {:ok, updated_object} =
                Utils.update_element_in_object(
@@ -302,7 +302,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
   describe "get_existing_like/2" do
     test "fetches existing like" do
       note_activity = insert(:note_activity)
-      assert object = Object.normalize(note_activity)
+      assert object = Object.normalize(note_activity, fetch: false)
 
       user = insert(:user)
       refute Utils.get_existing_like(user.ap_id, object)
@@ -320,7 +320,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
 
     test "fetches existing announce" do
       note_activity = insert(:note_activity)
-      assert object = Object.normalize(note_activity)
+      assert object = Object.normalize(note_activity, fetch: false)
       actor = insert(:user)
 
       {:ok, announce} = CommonAPI.repeat(note_activity.id, actor)
@@ -412,7 +412,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
   describe "lazy_put_activity_defaults/2" do
     test "returns map with id and published data" do
       note_activity = insert(:note_activity)
-      object = Object.normalize(note_activity)
+      object = Object.normalize(note_activity, fetch: false)
       res = Utils.lazy_put_activity_defaults(%{"context" => object.data["id"]})
       assert res["context"] == object.data["id"]
       assert res["context_id"] == object.id
@@ -431,7 +431,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
 
     test "returns activity data with object" do
       note_activity = insert(:note_activity)
-      object = Object.normalize(note_activity)
+      object = Object.normalize(note_activity, fetch: false)
 
       res =
         Utils.lazy_put_activity_defaults(%{
index f0389845dafd5733f5755673eaeb0e4dc1dd49c7..967acad19b8e4f23a85fff2bcc084454565779b8 100644 (file)
@@ -24,7 +24,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectViewTest do
 
   test "renders a note activity" do
     note = insert(:note_activity)
-    object = Object.normalize(note)
+    object = Object.normalize(note, fetch: false)
 
     result = ObjectView.render("object.json", %{object: note})
 
@@ -56,7 +56,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectViewTest do
 
   test "renders a like activity" do
     note = insert(:note_activity)
-    object = Object.normalize(note)
+    object = Object.normalize(note, fetch: false)
     user = insert(:user)
 
     {:ok, like_activity} = CommonAPI.favorite(user, note.id)
@@ -70,7 +70,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectViewTest do
 
   test "renders an announce activity" do
     note = insert(:note_activity)
-    object = Object.normalize(note)
+    object = Object.normalize(note, fetch: false)
     user = insert(:user)
 
     {:ok, announce_activity} = CommonAPI.repeat(note.id, user)
index fe6ddf0d683c1c50867178ecb8ad881bb2885b3d..5702c1b6f07877c02d822ea86a6ecb88cd948585 100644 (file)
@@ -80,6 +80,12 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
     assert %{"invisible" => true} = UserView.render("service.json", %{user: user})
   end
 
+  test "renders AKAs" do
+    akas = ["https://i.tusooa.xyz/users/test-pleroma"]
+    user = insert(:user, also_known_as: akas)
+    assert %{"alsoKnownAs" => ^akas} = UserView.render("user.json", %{user: user})
+  end
+
   describe "endpoints" do
     test "local users have a usable endpoints structure" do
       user = insert(:user)
index e50d1425b78c068851f434f03f1bf7222bf57d99..90b25b782a30b9a3390571051a13bc2f68f2737a 100644 (file)
@@ -422,10 +422,20 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
       assert json_response(conn, 200) |> length() == 3
     end
 
-    test "renders user's statuses with a limit", %{conn: conn, user: user} do
-      conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses?page_size=2")
+    test "renders user's statuses with pagination", %{conn: conn, user: user} do
+      conn1 = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses?page_size=1&page=1")
 
-      assert json_response(conn, 200) |> length() == 2
+      response1 = json_response(conn1, 200)
+
+      assert response1 |> length() == 1
+
+      conn2 = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses?page_size=1&page=2")
+
+      response2 = json_response(conn2, 200)
+
+      assert response2 |> length() == 1
+
+      refute response1 == response2
     end
 
     test "doesn't return private statuses by default", %{conn: conn, user: user} do
index dead1c09e4e887c426d41169491adaea1773e579..00e67a91cc356deef2c602a85c178ccb4c989d5e 100644 (file)
@@ -36,7 +36,7 @@ defmodule Pleroma.Web.AdminAPI.ChatControllerTest do
       {:ok, message} =
         CommonAPI.post_chat_message(user, recipient, "Hello darkness my old friend")
 
-      object = Object.normalize(message, false)
+      object = Object.normalize(message, fetch: false)
 
       chat = Chat.get(user.id, recipient.ap_id)
       recipient_chat = Chat.get(recipient.id, user.ap_id)
@@ -143,7 +143,7 @@ defmodule Pleroma.Web.AdminAPI.ChatControllerTest do
       recipient = insert(:user)
 
       {:ok, message} = CommonAPI.post_chat_message(user, recipient, "Yo")
-      object = Object.normalize(message, false)
+      object = Object.normalize(message, fetch: false)
       chat = Chat.get(user.id, recipient.ap_id)
       cm_ref = MessageReference.for_chat_and_object(chat, object)
 
@@ -183,7 +183,7 @@ defmodule Pleroma.Web.AdminAPI.ChatControllerTest do
       recipient = insert(:user)
 
       {:ok, message} = CommonAPI.post_chat_message(user, recipient, "Yo")
-      object = Object.normalize(message, false)
+      object = Object.normalize(message, fetch: false)
       chat = Chat.get(user.id, recipient.ap_id)
       cm_ref = MessageReference.for_chat_and_object(chat, object)
 
index 5705306c74a1fa92e58a16d1316bea2b8c90ecdf..67b0c578c426b78068628ec4ff70ba9f040f46a1 100644 (file)
@@ -953,6 +953,7 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do
     %{
       "deactivated" => user.deactivated,
       "id" => user.id,
+      "email" => user.email,
       "nickname" => user.nickname,
       "roles" => %{"admin" => false, "moderator" => false},
       "local" => user.local,
diff --git a/test/pleroma/web/admin_api/views/account_view_test.exs b/test/pleroma/web/admin_api/views/account_view_test.exs
new file mode 100644 (file)
index 0000000..f542145
--- /dev/null
@@ -0,0 +1,16 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.AdminAPI.AccountViewTest do
+  use Pleroma.DataCase, async: true
+  import Pleroma.Factory
+  alias Pleroma.Web.AdminAPI.AccountView
+
+  describe "show.json" do
+    test "renders the user's email" do
+      user = insert(:user, email: "yolo@yolofam.tld")
+      assert %{"email" => "yolo@yolofam.tld"} = AccountView.render("show.json", %{user: user})
+    end
+  end
+end
index 390d7bbebf87cc1f67f3ffa74db037b6065cb4c0..a4748990ed8ce6aa502b492d488e194293b75203 100644 (file)
@@ -9,6 +9,7 @@ defmodule Pleroma.Web.AdminAPI.ModerationLogViewTest do
   describe "renders `report_note_delete` log messages" do
     setup do
       log1 = %Pleroma.ModerationLog{
+        id: 1,
         data: %{
           "action" => "report_note_delete",
           "actor" => %{"id" => "A1I7G8", "nickname" => "admin", "type" => "user"},
@@ -21,6 +22,7 @@ defmodule Pleroma.Web.AdminAPI.ModerationLogViewTest do
       }
 
       log2 = %Pleroma.ModerationLog{
+        id: 2,
         data: %{
           "action" => "report_note_delete",
           "actor" => %{"id" => "A1I7G8", "nickname" => "admin", "type" => "user"},
@@ -42,6 +44,7 @@ defmodule Pleroma.Web.AdminAPI.ModerationLogViewTest do
              ) == %{
                items: [
                  %{
+                   id: 1,
                    data: %{
                      "action" => "report_note_delete",
                      "actor" => %{"id" => "A1I7G8", "nickname" => "admin", "type" => "user"},
@@ -59,6 +62,7 @@ defmodule Pleroma.Web.AdminAPI.ModerationLogViewTest do
                    time: 1_605_622_400
                  },
                  %{
+                   id: 2,
                    data: %{
                      "action" => "report_note_delete",
                      "actor" => %{"id" => "A1I7G8", "nickname" => "admin", "type" => "user"},
@@ -82,6 +86,7 @@ defmodule Pleroma.Web.AdminAPI.ModerationLogViewTest do
 
     test "renders `report_note_delete` log message", %{log1: log} do
       assert ModerationLogView.render("show.json", %{log_entry: log}) == %{
+               id: 1,
                data: %{
                  "action" => "report_note_delete",
                  "actor" => %{"id" => "A1I7G8", "nickname" => "admin", "type" => "user"},
index ff345320875e4368554e96b60e429cbd5ae4eb13..3914751b5281680868bde5dfc78ccd7c63a42c64 100644 (file)
@@ -143,4 +143,29 @@ defmodule Pleroma.Web.AdminAPI.ReportViewTest do
 
     assert %{} = ReportView.render("show.json", Report.extract_report_info(activity))
   end
+
+  test "reports are ordered newest first" do
+    user = insert(:user)
+    other_user = insert(:user)
+
+    {:ok, report1} =
+      CommonAPI.report(user, %{
+        account_id: other_user.id,
+        comment: "first report"
+      })
+
+    {:ok, report2} =
+      CommonAPI.report(user, %{
+        account_id: other_user.id,
+        comment: "second report"
+      })
+
+    %{reports: rendered} =
+      ReportView.render("index.json",
+        reports: Pleroma.Web.ActivityPub.Utils.get_reports(%{}, 1, 50)
+      )
+
+    assert report2.id == rendered |> Enum.at(0) |> Map.get(:id)
+    assert report1.id == rendered |> Enum.at(1) |> Map.get(:id)
+  end
 end
index 585b2c174c9564c4aa2ccb408c7847f39374b671..56a3d653150a06f792d265f3d4052ea8e6d331a6 100644 (file)
@@ -39,7 +39,7 @@ defmodule Pleroma.Web.CommonAPITest do
           poll: %{expires_in: 600, options: ["reimu", "marisa"]}
         })
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       assert object.data["type"] == "Question"
       assert object.data["oneOf"] |> length() == 2
@@ -174,7 +174,7 @@ defmodule Pleroma.Web.CommonAPITest do
 
       assert other_user.ap_id not in activity.recipients
 
-      object = Object.normalize(activity, false)
+      object = Object.normalize(activity, fetch: false)
 
       assert object.data["content"] == "uguu<br/>uguuu"
     end
@@ -194,7 +194,7 @@ defmodule Pleroma.Web.CommonAPITest do
 
       assert other_user.ap_id not in activity.recipients
 
-      object = Object.normalize(activity, false)
+      object = Object.normalize(activity, fetch: false)
 
       assert object.data["content"] ==
                "<a href=\"https://example.org\" rel=\"ugc\">https://example.org</a> is the site of <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{
@@ -215,7 +215,7 @@ defmodule Pleroma.Web.CommonAPITest do
 
       assert activity.data["type"] == "Create"
       assert activity.local
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       assert object.data["type"] == "ChatMessage"
       assert object.data["to"] == [recipient.ap_id]
@@ -281,7 +281,7 @@ defmodule Pleroma.Web.CommonAPITest do
 
       clear_config([:instance, :federating], true)
 
-      Object.normalize(post, false)
+      Object.normalize(post, fetch: false)
       |> Object.prune()
 
       with_mock Pleroma.Web.Federator,
@@ -491,7 +491,7 @@ defmodule Pleroma.Web.CommonAPITest do
     user = insert(:user)
     {:ok, activity} = CommonAPI.post(user, %{status: "#2hu #2HU"})
 
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
 
     assert object.data["tag"] == ["2hu"]
   end
@@ -500,10 +500,23 @@ defmodule Pleroma.Web.CommonAPITest do
     user = insert(:user)
     {:ok, activity} = CommonAPI.post(user, %{status: ":firefox:"})
 
-    assert Object.normalize(activity).data["emoji"]["firefox"]
+    assert Object.normalize(activity, fetch: false).data["emoji"]["firefox"]
   end
 
   describe "posting" do
+    test "it adds an emoji on an external site" do
+      user = insert(:user)
+      {:ok, activity} = CommonAPI.post(user, %{status: "hey :external_emoji:"})
+
+      assert %{"external_emoji" => url} = Object.normalize(activity).data["emoji"]
+      assert url == "https://example.com/emoji.png"
+
+      {:ok, activity} = CommonAPI.post(user, %{status: "hey :blank:"})
+
+      assert %{"blank" => url} = Object.normalize(activity).data["emoji"]
+      assert url == "#{Pleroma.Web.base_url()}/emoji/blank.png"
+    end
+
     test "deactivated users can't post" do
       user = insert(:user, deactivated: true)
       assert {:error, _} = CommonAPI.post(user, %{status: "ye"})
@@ -539,7 +552,7 @@ defmodule Pleroma.Web.CommonAPITest do
           content_type: "text/html"
         })
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       assert object.data["content"] == "<p><b>2hu</b></p>alert(&#39;xss&#39;)"
       assert object.data["source"] == post
@@ -556,7 +569,7 @@ defmodule Pleroma.Web.CommonAPITest do
           content_type: "text/markdown"
         })
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       assert object.data["content"] == "<p><b>2hu</b></p>alert(&#39;xss&#39;)"
       assert object.data["source"] == post
@@ -1211,7 +1224,7 @@ defmodule Pleroma.Web.CommonAPITest do
           poll: %{options: ["Yes", "No"], expires_in: 20}
         })
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       {:ok, _, object} = CommonAPI.vote(other_user, object, [0])
 
@@ -1231,7 +1244,7 @@ defmodule Pleroma.Web.CommonAPITest do
           length: 180_000
         })
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       assert object.data["title"] == "lain radio episode 1"
 
@@ -1250,7 +1263,7 @@ defmodule Pleroma.Web.CommonAPITest do
           visibility: "private"
         })
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       assert object.data["title"] == "lain radio episode 1"
 
index b4abcf6f2394d02fe66ad7d6cef215e8db807522..48dc3b404e9ba0fcac191fe0264d457338cbc89c 100644 (file)
@@ -24,7 +24,7 @@ defmodule Pleroma.Web.Feed.TagControllerTest do
     user = insert(:user)
     {:ok, activity1} = CommonAPI.post(user, %{status: "yeah #PleromaArt"})
 
-    object = Object.normalize(activity1)
+    object = Object.normalize(activity1, fetch: false)
 
     object_data =
       Map.put(object.data, "attachment", [
@@ -91,7 +91,7 @@ defmodule Pleroma.Web.Feed.TagControllerTest do
     user = insert(:user)
     {:ok, activity1} = CommonAPI.post(user, %{status: "yeah #PleromaArt"})
 
-    object = Object.normalize(activity1)
+    object = Object.normalize(activity1, fetch: false)
 
     object_data =
       Map.put(object.data, "attachment", [
@@ -147,8 +147,8 @@ defmodule Pleroma.Web.Feed.TagControllerTest do
              "https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4"
            ]
 
-    obj1 = Object.normalize(activity1)
-    obj2 = Object.normalize(activity2)
+    obj1 = Object.normalize(activity1, fetch: false)
+    obj2 = Object.normalize(activity2, fetch: false)
 
     assert xpath(xml, ~x"//channel/item/description/text()"sl) == [
              HtmlEntities.decode(FeedView.activity_content(obj2.data)),
index 16f00271704fee1e19999a5179025c38ab5805e9..50445862bb650083089abf424932b5030f04276a 100644 (file)
@@ -58,7 +58,7 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
         )
 
       note_activity2 = insert(:note_activity, note: note2)
-      object = Object.normalize(note_activity)
+      object = Object.normalize(note_activity, fetch: false)
 
       [user: user, object: object, max_id: note_activity2.id]
     end
index f6285853a16d7a5db189fdcd48eac676f53cbc38..cc7b3cf8b4b52ec6cdef92d7819ab6022870192b 100644 (file)
@@ -469,6 +469,21 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
                }
              ] = result
     end
+
+    test "paginates a user's statuses", %{user: user, conn: conn} do
+      {:ok, post_1} = CommonAPI.post(user, %{status: "first post"})
+      {:ok, post_2} = CommonAPI.post(user, %{status: "second post"})
+
+      response_1 = get(conn, "/api/v1/accounts/#{user.id}/statuses?limit=1")
+      assert [res] = json_response(response_1, 200)
+      assert res["id"] == post_2.id
+
+      response_2 = get(conn, "/api/v1/accounts/#{user.id}/statuses?limit=1&max_id=#{res["id"]}")
+      assert [res] = json_response(response_2, 200)
+      assert res["id"] == post_1.id
+
+      refute response_1 == response_2
+    end
   end
 
   defp local_and_remote_activities(%{local: local, remote: remote}) do
index 95e27623d7111358784cb804edc7d9d9b7ab11bc..71cea8462183a356c7d4ce619913750d40b0b92e 100644 (file)
@@ -20,7 +20,7 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do
           poll: %{options: ["what Mastodon't", "n't what Mastodoes"], expires_in: 20}
         })
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       conn = get(conn, "/api/v1/polls/#{object.id}")
 
@@ -39,7 +39,7 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do
           visibility: "private"
         })
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       conn = get(conn, "/api/v1/polls/#{object.id}")
 
@@ -63,7 +63,7 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do
           }
         })
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       conn =
         conn
@@ -85,7 +85,7 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do
           poll: %{options: ["Yes", "No"], expires_in: 20}
         })
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       assert conn
              |> put_req_header("content-type", "application/json")
@@ -106,7 +106,7 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do
           poll: %{options: ["half empty", "half full"], expires_in: 20}
         })
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       assert conn
              |> put_req_header("content-type", "application/json")
@@ -129,7 +129,7 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do
           poll: %{options: ["Yes", "No"], expires_in: 20}
         })
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       conn =
         conn
@@ -158,7 +158,7 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do
           visibility: "private"
         })
 
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       conn =
         conn
index 1045ab2653044c8b5d3fc2b221f11611b0a39ab4..664bdce01d7601fd3cf6828542b1a3a62ba0166e 100644 (file)
@@ -309,7 +309,7 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
         })
 
       capture_log(fn ->
-        q = Object.normalize(activity).data["id"]
+        q = Object.normalize(activity, fetch: false).data["id"]
 
         results =
           conn
index de542e5df8e654ea0e4994a02fe2df93b55ad62a..ffff0ae9d6cde82eabe62b3401b6c14ce0a73215 100644 (file)
@@ -800,7 +800,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
     test "when you created it" do
       %{user: author, conn: conn} = oauth_access(["write:statuses"])
       activity = insert(:note_activity, user: author)
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       content = object.data["content"]
       source = object.data["source"]
@@ -1374,7 +1374,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
 
     activity = Activity.get_by_id_with_object(id)
 
-    assert Object.normalize(activity).data["inReplyTo"] == Object.normalize(replied_to).data["id"]
+    assert Object.normalize(activity, fetch: false).data["inReplyTo"] ==
+             Object.normalize(replied_to, fetch: false).data["id"]
+
     assert Activity.get_in_reply_to_activity(activity).id == replied_to.id
 
     # Reblog from the third user
index 023726468ef070892b7ee9808ddcc633da2753ea..e3e437a19c538e105c57f9314d8d9b8c08f18cad 100644 (file)
@@ -218,6 +218,25 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
       assert update_activity.data["object"]["name"] == "markorepairs"
     end
 
+    test "updates the user's AKAs", %{conn: conn} do
+      conn =
+        patch(conn, "/api/v1/accounts/update_credentials", %{
+          "also_known_as" => ["https://mushroom.kingdom/users/mario"]
+        })
+
+      assert user_data = json_response_and_validate_schema(conn, 200)
+      assert user_data["pleroma"]["also_known_as"] == ["https://mushroom.kingdom/users/mario"]
+    end
+
+    test "doesn't update non-url akas", %{conn: conn} do
+      conn =
+        patch(conn, "/api/v1/accounts/update_credentials", %{
+          "also_known_as" => ["aReallyCoolGuy"]
+        })
+
+      assert json_response_and_validate_schema(conn, 403)
+    end
+
     test "updates the user's avatar", %{user: user, conn: conn} do
       new_avatar = %Plug.Upload{
         content_type: "image/jpeg",
index 8c77f14d44e06103f3de7b248ca464f49f26b450..f9afd0afc2ca54089eb003e14588b8362b7170d4 100644 (file)
@@ -35,7 +35,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
           "<script src=\"invalid-html\"></script><span>valid html</span>. a<br>b<br/>c<br >d<br />f '&<>\"",
         inserted_at: ~N[2017-08-15 15:47:06.597036],
         emoji: %{"karjalanpiirakka" => "/file.png"},
-        raw_bio: "valid html. a\nb\nc\nd\nf '&<>\""
+        raw_bio: "valid html. a\nb\nc\nd\nf '&<>\"",
+        also_known_as: ["https://shitposter.zone/users/shp"]
       })
 
     expected = %{
@@ -75,6 +76,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
       },
       pleroma: %{
         ap_id: user.ap_id,
+        also_known_as: ["https://shitposter.zone/users/shp"],
         background_image: "https://example.com/images/asuka_hospital.png",
         favicon: nil,
         confirmation_pending: false,
@@ -173,6 +175,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
       },
       pleroma: %{
         ap_id: user.ap_id,
+        also_known_as: [],
         background_image: nil,
         favicon: nil,
         confirmation_pending: false,
index 9de11a87e4238d04ae1960bb37d5dcc24b5eef25..79dd23a5149c5b10e4622a5b3844f69fa4238567 100644 (file)
@@ -44,7 +44,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
 
     {:ok, [notification]} = Notification.create_notifications(activity)
 
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
     chat = Chat.get(recipient.id, user.ap_id)
 
     cm_ref = MessageReference.for_chat_and_object(chat, object)
index c655ca438ff6351e4aca0488f8a60c3762408515..f83e5b368f796d9df2128d31600946f54ded257d 100644 (file)
@@ -29,7 +29,7 @@ defmodule Pleroma.Web.MastodonAPI.PollViewTest do
         }
       })
 
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
 
     expected = %{
       emojis: [],
@@ -72,7 +72,7 @@ defmodule Pleroma.Web.MastodonAPI.PollViewTest do
 
     voter = insert(:user)
 
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
 
     {:ok, _votes, object} = CommonAPI.vote(voter, object, [0, 1])
 
@@ -98,7 +98,7 @@ defmodule Pleroma.Web.MastodonAPI.PollViewTest do
         }
       })
 
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
 
     assert %{emojis: [%{shortcode: "blank"}]} = PollView.render("show.json", %{object: object})
   end
@@ -117,7 +117,7 @@ defmodule Pleroma.Web.MastodonAPI.PollViewTest do
         }
       })
 
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
 
     {:ok, _, object} = CommonAPI.vote(other_user, object, [1, 2])
 
@@ -129,7 +129,7 @@ defmodule Pleroma.Web.MastodonAPI.PollViewTest do
   end
 
   test "does not crash on polls with no end date" do
-    object = Object.normalize("https://skippers-bin.com/notes/7x9tmrp97i")
+    object = Object.normalize("https://skippers-bin.com/notes/7x9tmrp97i", fetch: true)
     result = PollView.render("show.json", %{object: object})
 
     assert result[:expires_at] == nil
@@ -153,7 +153,7 @@ defmodule Pleroma.Web.MastodonAPI.PollViewTest do
         }
       })
 
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
 
     assert %{
              options: [
index fa90667168762f79ae5bcff029b13fc9f132037a..789acb4878d25eba80b72a19868bb92715f3201d 100644 (file)
@@ -61,7 +61,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
     {:ok, activity} = CommonAPI.post(user, %{status: "yo"})
 
     activity
-    |> Object.normalize(false)
+    |> Object.normalize(fetch: false)
     |> Object.update_data(%{"reactions" => %{"☕" => [user.ap_id], "x" => 1}})
 
     activity = Activity.get_by_id(activity.id)
@@ -204,7 +204,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
 
   test "a note with null content" do
     note = insert(:note_activity)
-    note_object = Object.normalize(note)
+    note_object = Object.normalize(note, fetch: false)
 
     data =
       note_object.data
@@ -223,7 +223,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
 
   test "a note activity" do
     note = insert(:note_activity)
-    object_data = Object.normalize(note).data
+    object_data = Object.normalize(note, fetch: false).data
     user = User.get_cached_by_ap_id(note.data["actor"])
 
     convo_id = Utils.context_to_conversation_id(object_data["context"])
index 65b2c22dbe45bb16ac9a5335f5a3f5ae8675603d..f21180a89d12283884c05e80b2f9b04bb7a650a7 100644 (file)
@@ -72,7 +72,7 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do
 
     test "redirects to /notice/id for html format", %{conn: conn} do
       note_activity = insert(:note_activity)
-      object = Object.normalize(note_activity)
+      object = Object.normalize(note_activity, fetch: false)
       [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, object.data["id"]))
       url = "/objects/#{uuid}"
 
@@ -82,7 +82,7 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do
 
     test "404s on private objects", %{conn: conn} do
       note_activity = insert(:direct_note_activity)
-      object = Object.normalize(note_activity)
+      object = Object.normalize(note_activity, fetch: false)
       [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, object.data["id"]))
 
       conn
@@ -133,7 +133,7 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do
       conn: conn
     } do
       note_activity = insert(:note_activity)
-      expected_redirect_url = Object.normalize(note_activity).data["id"]
+      expected_redirect_url = Object.normalize(note_activity, fetch: false).data["id"]
 
       redirect_url =
         conn
@@ -230,7 +230,7 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do
   describe "GET /notice/:id/embed_player" do
     setup do
       note_activity = insert(:note_activity)
-      object = Pleroma.Object.normalize(note_activity)
+      object = Pleroma.Object.normalize(note_activity, fetch: false)
 
       object_data =
         Map.put(object.data, "attachment", [
@@ -287,7 +287,7 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do
 
     test "404s when attachment is empty", %{conn: conn} do
       note_activity = insert(:note_activity)
-      object = Pleroma.Object.normalize(note_activity)
+      object = Pleroma.Object.normalize(note_activity, fetch: false)
       object_data = Map.put(object.data, "attachment", [])
 
       object
@@ -301,7 +301,7 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do
 
     test "404s when attachment isn't audio or video", %{conn: conn} do
       note_activity = insert(:note_activity)
-      object = Pleroma.Object.normalize(note_activity)
+      object = Pleroma.Object.normalize(note_activity, fetch: false)
 
       object_data =
         Map.put(object.data, "attachment", [
index 415c3decdbca7ffb24d54fdf0648c94182fd29fb..24efeeb73a36ef445a34ceec718fab2df7601ae5 100644 (file)
@@ -22,7 +22,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do
       {:ok, create} = CommonAPI.post_chat_message(other_user, user, "sup")
       {:ok, _create} = CommonAPI.post_chat_message(other_user, user, "sup part 2")
       {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
-      object = Object.normalize(create, false)
+      object = Object.normalize(create, fetch: false)
       cm_ref = MessageReference.for_chat_and_object(chat, object)
 
       assert cm_ref.unread == true
@@ -52,7 +52,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do
       {:ok, create} = CommonAPI.post_chat_message(other_user, user, "sup")
       {:ok, _create} = CommonAPI.post_chat_message(other_user, user, "sup part 2")
       {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
-      object = Object.normalize(create, false)
+      object = Object.normalize(create, fetch: false)
       cm_ref = MessageReference.for_chat_and_object(chat, object)
 
       assert cm_ref.unread == true
@@ -158,7 +158,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do
 
       {:ok, other_message} = CommonAPI.post_chat_message(recipient, user, "nico nico ni")
 
-      object = Object.normalize(message, false)
+      object = Object.normalize(message, fetch: false)
 
       chat = Chat.get(user.id, recipient.ap_id)
 
@@ -176,7 +176,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do
       assert %{data: %{"type" => "Tombstone"}} = Object.get_by_id(object.id)
 
       # Deleting other people's messages just removes the reference
-      object = Object.normalize(other_message, false)
+      object = Object.normalize(other_message, fetch: false)
       cm_ref = MessageReference.for_chat_and_object(chat, object)
 
       result =
diff --git a/test/pleroma/web/pleroma_api/views/backup_view_test.exs b/test/pleroma/web/pleroma_api/views/backup_view_test.exs
new file mode 100644 (file)
index 0000000..7dda848
--- /dev/null
@@ -0,0 +1,18 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.PleromaAPI.BackupViewTest do
+  use Pleroma.DataCase, async: true
+  alias Pleroma.User.Backup
+  alias Pleroma.Web.PleromaAPI.BackupView
+  import Pleroma.Factory
+
+  test "it renders the ID" do
+    user = insert(:user)
+    backup = Backup.new(user)
+
+    result = BackupView.render("show.json", backup: backup)
+    assert result.id == backup.id
+  end
+end
index 93eef00a2c550b4c045545916d0568218f02d004..0966e91664ee7450e5d6741387684a671fc45770 100644 (file)
@@ -31,7 +31,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatMessageReferenceViewTest do
 
     chat = Chat.get(user.id, recipient.ap_id)
 
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
 
     cm_ref = MessageReference.for_chat_and_object(chat, object)
 
@@ -58,7 +58,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatMessageReferenceViewTest do
         media_id: upload.id
       )
 
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
 
     cm_ref = MessageReference.for_chat_and_object(chat, object)
 
index b60b597e857e16893ab84eb31df686c3c770f7d6..1cc5f16ba97b28074cab3ad893fa20d6a550269a 100644 (file)
@@ -35,7 +35,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatViewTest do
 
     {:ok, chat_message_creation} = CommonAPI.post_chat_message(user, recipient, "hello")
 
-    chat_message = Object.normalize(chat_message_creation, false)
+    chat_message = Object.normalize(chat_message_creation, fetch: false)
 
     {:ok, chat} = Chat.get_or_create(user.id, recipient.ap_id)
 
index 326a67963410e71c17ef096c14a25827b95c038f..d14e0bdefc7855e577455b0471ae1dd9340fb5a6 100644 (file)
@@ -118,7 +118,7 @@ defmodule Pleroma.Web.Push.ImplTest do
           "<span>Lorem ipsum dolor sit amet</span>, consectetur :firefox: adipiscing elit. Fusce sagittis finibus turpis."
       })
 
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
 
     assert Impl.format_body(
              %{
@@ -137,7 +137,7 @@ defmodule Pleroma.Web.Push.ImplTest do
     user = insert(:user, nickname: "Bob")
     other_user = insert(:user)
     {:ok, _, _, activity} = CommonAPI.follow(user, other_user)
-    object = Object.normalize(activity, false)
+    object = Object.normalize(activity, fetch: false)
 
     assert Impl.format_body(%{activity: activity, type: "follow"}, user, object) ==
              "@Bob has followed you"
@@ -156,7 +156,7 @@ defmodule Pleroma.Web.Push.ImplTest do
       })
 
     {:ok, announce_activity} = CommonAPI.repeat(activity.id, user)
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
 
     assert Impl.format_body(%{activity: announce_activity}, user, object) ==
              "@#{user.nickname} repeated: Lorem ipsum dolor sit amet, consectetur  adipiscing elit. Fusce sagittis fini..."
@@ -175,7 +175,7 @@ defmodule Pleroma.Web.Push.ImplTest do
       })
 
     {:ok, activity} = CommonAPI.favorite(user, activity.id)
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
 
     assert Impl.format_body(%{activity: activity, type: "favourite"}, user, object) ==
              "@Bob has favorited your post"
@@ -193,7 +193,7 @@ defmodule Pleroma.Web.Push.ImplTest do
       })
 
     {:ok, activity} = CommonAPI.react_with_emoji(activity.id, user, "👍")
-    object = Object.normalize(activity)
+    object = Object.normalize(activity, fetch: false)
 
     assert Impl.format_body(%{activity: activity, type: "pleroma:emoji_reaction"}, user, object) ==
              "@Bob reacted with 👍"
@@ -221,7 +221,7 @@ defmodule Pleroma.Web.Push.ImplTest do
       recipient = insert(:user)
 
       {:ok, chat} = CommonAPI.post_chat_message(user, recipient, "hey")
-      object = Object.normalize(chat, false)
+      object = Object.normalize(chat, fetch: false)
       [notification] = Notification.for_user(recipient)
 
       res = Impl.build_content(notification, user, object)
@@ -245,7 +245,7 @@ defmodule Pleroma.Web.Push.ImplTest do
       {:ok, upload} = ActivityPub.upload(file, actor: user.ap_id)
 
       {:ok, chat} = CommonAPI.post_chat_message(user, recipient, nil, media_id: upload.id)
-      object = Object.normalize(chat, false)
+      object = Object.normalize(chat, fetch: false)
       [notification] = Notification.for_user(recipient)
 
       res = Impl.build_content(notification, user, object)
@@ -271,7 +271,7 @@ defmodule Pleroma.Web.Push.ImplTest do
       notif = insert(:notification, user: user2, activity: activity)
 
       actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       assert Impl.build_content(notif, actor, object) == %{
                body: "New Direct Message"
@@ -286,7 +286,7 @@ defmodule Pleroma.Web.Push.ImplTest do
       notif = insert(:notification, user: user2, activity: activity, type: "mention")
 
       actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       assert Impl.build_content(notif, actor, object) == %{
                body: "New Mention"
@@ -297,7 +297,7 @@ defmodule Pleroma.Web.Push.ImplTest do
       notif = insert(:notification, user: user2, activity: activity, type: "favourite")
 
       actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       assert Impl.build_content(notif, actor, object) == %{
                body: "New Favorite"
@@ -320,7 +320,7 @@ defmodule Pleroma.Web.Push.ImplTest do
       notif = insert(:notification, user: user2, activity: activity)
 
       actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       assert Impl.build_content(notif, actor, object) == %{
                body:
@@ -338,7 +338,7 @@ defmodule Pleroma.Web.Push.ImplTest do
       notif = insert(:notification, user: user2, activity: activity, type: "mention")
 
       actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       assert Impl.build_content(notif, actor, object) == %{
                body:
@@ -351,7 +351,7 @@ defmodule Pleroma.Web.Push.ImplTest do
       notif = insert(:notification, user: user2, activity: activity, type: "favourite")
 
       actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       assert Impl.build_content(notif, actor, object) == %{
                body: "@Bob has favorited your post",
index ad66ddc9d6dc75876bbc5905fae36f6d023a6d64..764b799bbea215e3cc0f2ceac5e293412d7de82e 100644 (file)
@@ -266,7 +266,7 @@ defmodule Pleroma.Web.StreamerTest do
       {:ok, create_activity} =
         CommonAPI.post_chat_message(other_user, user, "hey cirno", idempotency_key: "123")
 
-      object = Object.normalize(create_activity, false)
+      object = Object.normalize(create_activity, fetch: false)
       chat = Chat.get(user.id, other_user.ap_id)
       cm_ref = MessageReference.for_chat_and_object(chat, object)
       cm_ref = %{cm_ref | chat: chat, object: object}
@@ -284,7 +284,7 @@ defmodule Pleroma.Web.StreamerTest do
       other_user = insert(:user)
 
       {:ok, create_activity} = CommonAPI.post_chat_message(other_user, user, "hey cirno")
-      object = Object.normalize(create_activity, false)
+      object = Object.normalize(create_activity, fetch: false)
       chat = Chat.get(user.id, other_user.ap_id)
       cm_ref = MessageReference.for_chat_and_object(chat, object)
       cm_ref = %{cm_ref | chat: chat, object: object}
index 0023f1e810e4cee2bed55d0cc49f73b51fe9f334..ce9eb0650a7d05050847da2f0df4f02a8a25392b 100644 (file)
@@ -30,14 +30,24 @@ defmodule Pleroma.Web.WebFinger.WebFingerControllerTest do
   end
 
   test "Webfinger JRD" do
-    user = insert(:user)
+    user =
+      insert(:user,
+        ap_id: "https://hyrule.world/users/zelda",
+        also_known_as: ["https://mushroom.kingdom/users/toad"]
+      )
 
     response =
       build_conn()
       |> put_req_header("accept", "application/jrd+json")
       |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@localhost")
+      |> json_response(200)
+
+    assert response["subject"] == "acct:#{user.nickname}@localhost"
 
-    assert json_response(response, 200)["subject"] == "acct:#{user.nickname}@localhost"
+    assert response["aliases"] == [
+             "https://hyrule.world/users/zelda",
+             "https://mushroom.kingdom/users/toad"
+           ]
   end
 
   test "it returns 404 when user isn't found (JSON)" do
@@ -51,14 +61,20 @@ defmodule Pleroma.Web.WebFinger.WebFingerControllerTest do
   end
 
   test "Webfinger XML" do
-    user = insert(:user)
+    user =
+      insert(:user,
+        ap_id: "https://hyrule.world/users/zelda",
+        also_known_as: ["https://mushroom.kingdom/users/toad"]
+      )
 
     response =
       build_conn()
       |> put_req_header("accept", "application/xrd+xml")
       |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@localhost")
+      |> response(200)
 
-    assert response(response, 200)
+    assert response =~ "<Alias>https://hyrule.world/users/zelda</Alias>"
+    assert response =~ "<Alias>https://mushroom.kingdom/users/toad</Alias>"
   end
 
   test "it returns 404 when user isn't found (XML)" do
index f3eddf7b14a12531e6778fb15db50466f32da585..c9e2091a9c76945b7a49dab0e4cdebb3709c277b 100644 (file)
@@ -36,7 +36,7 @@ defmodule Pleroma.Workers.ScheduledActivityWorkerTest do
 
     refute Repo.get(ScheduledActivity, scheduled_activity.id)
     activity = Repo.all(Pleroma.Activity) |> Enum.find(&(&1.actor == user.ap_id))
-    assert Pleroma.Object.normalize(activity).data["content"] == "hi"
+    assert Pleroma.Object.normalize(activity, fetch: false).data["content"] == "hi"
   end
 
   test "adds log message if ScheduledActivity isn't find" do
index 02f49c5906a2847c4c2d6aff7d8c0b1b95512765..f20e3d955e33dafcdd1728da1bc24d4372b3e4df 100644 (file)
@@ -138,6 +138,8 @@ defmodule Pleroma.Web.ConnCase do
 
     Pleroma.DataCase.stub_pipeline()
 
+    Mox.verify_on_exit!()
+
     {:ok, conn: Phoenix.ConnTest.build_conn()}
   end
 end
index 5c657c1d92cd9a656249ba80c8da8ba08d31018c..0b41f0f635a7cd0ccffc38e239d3f1d237f89046 100644 (file)
@@ -85,6 +85,8 @@ defmodule Pleroma.DataCase do
 
     stub_pipeline()
 
+    Mox.verify_on_exit!()
+
     :ok
   end
 
index 8eb07dc3c19e4f54d24f5372a8a46a58147a29d3..e02acb89b7c4077ca9d7b7d1d18bd695c413f398 100644 (file)
@@ -259,7 +259,7 @@ defmodule Pleroma.Factory do
 
   def like_activity_factory(attrs \\ %{}) do
     note_activity = attrs[:note_activity] || insert(:note_activity)
-    object = Object.normalize(note_activity)
+    object = Object.normalize(note_activity, fetch: false)
     user = insert(:user)
 
     data =
index a600a64581d5700d8442a3e073910f290f1ea29c..442ff5b7199e1f1bedacf4a7ee86f1e4855fe816 100644 (file)
@@ -13,7 +13,10 @@ Mox.defmock(Pleroma.Web.ActivityPub.MRFMock,
 )
 
 Mox.defmock(Pleroma.Web.ActivityPub.ActivityPubMock,
-  for: Pleroma.Web.ActivityPub.ActivityPub.Persisting
+  for: [
+    Pleroma.Web.ActivityPub.ActivityPub.Persisting,
+    Pleroma.Web.ActivityPub.ActivityPub.Streaming
+  ]
 )
 
 Mox.defmock(Pleroma.Web.ActivityPub.SideEffectsMock,
@@ -23,3 +26,5 @@ Mox.defmock(Pleroma.Web.ActivityPub.SideEffectsMock,
 Mox.defmock(Pleroma.Web.FederatorMock, for: Pleroma.Web.Federator.Publishing)
 
 Mox.defmock(Pleroma.ConfigMock, for: Pleroma.Config.Getting)
+
+Mox.defmock(Pleroma.LoggerMock, for: Pleroma.Logging)