summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--config/config.exs8
-rw-r--r--lib/pleroma/web/activity_pub/mrf/steal_emoji_policy.ex86
-rw-r--r--lib/pleroma/web/pleroma_api/views/backup_view.ex1
-rw-r--r--lib/pleroma/web/plugs/uploaded_media.ex9
-rw-r--r--priv/repo/migrations/20201231185546_confirm_logged_in_users.exs22
-rw-r--r--test/pleroma/repo/migrations/confirm_logged_in_users_test.exs40
-rw-r--r--test/pleroma/web/activity_pub/mrf/steal_emoji_policy_test.exs103
-rw-r--r--test/pleroma/web/pleroma_api/views/backup_view_test.exs18
9 files changed, 204 insertions, 84 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b70302bbf..25b24bf07 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -60,6 +60,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Fix ability to update Pleroma Chat push notifications with PUT /api/v1/push/subscription and alert type pleroma:chat_mention
- Emoji Reaction activity filtering from blocked and muted accounts.
+- StealEmojiPolicy creates dir for emojis, if it doesn't exist.
## [2.2.1] - 2020-12-22
diff --git a/config/config.exs b/config/config.exs
index d6d116314..7b14fbfe5 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -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
diff --git a/lib/pleroma/web/activity_pub/mrf/steal_emoji_policy.ex b/lib/pleroma/web/activity_pub/mrf/steal_emoji_policy.ex
index 2858af9eb..788f21261 100644
--- a/lib/pleroma/web/activity_pub/mrf/steal_emoji_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/steal_emoji_policy.ex
@@ -10,73 +10,75 @@ defmodule Pleroma.Web.ActivityPub.MRF.StealEmojiPolicy do
@moduledoc "Detect new emojis by their shortcode and steals them"
@behaviour Pleroma.Web.ActivityPub.MRF
- defp remote_host?(host), do: host != Config.get([Pleroma.Web.Endpoint, :url, :host])
-
defp accept_host?(host), do: host in Config.get([:mrf_steal_emoji, :hosts], [])
- defp steal_emoji({shortcode, url}) do
+ defp steal_emoji({shortcode, url}, emoji_dir_path) do
url = Pleroma.Web.MediaProxy.url(url)
- {:ok, response} = Pleroma.HTTP.get(url)
- size_limit = Config.get([:mrf_steal_emoji, :size_limit], 50_000)
- if byte_size(response.body) <= size_limit do
- emoji_dir_path =
- Config.get(
- [:mrf_steal_emoji, :path],
- Path.join(Config.get([:instance, :static_dir]), "emoji/stolen")
+ with {:ok, %{status: status} = response} when status in 200..299 <- Pleroma.HTTP.get(url) do
+ size_limit = Config.get([:mrf_steal_emoji, :size_limit], 50_000)
+
+ if byte_size(response.body) <= size_limit do
+ extension =
+ url
+ |> URI.parse()
+ |> Map.get(:path)
+ |> Path.basename()
+ |> Path.extname()
+
+ file_path = Path.join(emoji_dir_path, shortcode <> (extension || ".png"))
+
+ case File.write(file_path, response.body) do
+ :ok ->
+ shortcode
+
+ e ->
+ Logger.warn("MRF.StealEmojiPolicy: Failed to write to #{file_path}: #{inspect(e)}")
+ nil
+ end
+ else
+ Logger.debug(
+ "MRF.StealEmojiPolicy: :#{shortcode}: at #{url} (#{byte_size(response.body)} B) over size limit (#{
+ size_limit
+ } B)"
)
- extension =
- url
- |> URI.parse()
- |> Map.get(:path)
- |> Path.basename()
- |> Path.extname()
-
- file_path = Path.join([emoji_dir_path, shortcode <> (extension || ".png")])
-
- try do
- :ok = File.write(file_path, response.body)
-
- shortcode
- rescue
- e ->
- Logger.warn("MRF.StealEmojiPolicy: Failed to write to #{file_path}: #{inspect(e)}")
- nil
+ nil
end
else
- Logger.debug(
- "MRF.StealEmojiPolicy: :#{shortcode}: at #{url} (#{byte_size(response.body)} B) over size limit (#{
- size_limit
- } B)"
- )
-
- nil
+ e ->
+ Logger.warn("MRF.StealEmojiPolicy: Failed to fetch #{url}: #{inspect(e)}")
+ nil
end
- rescue
- e ->
- Logger.warn("MRF.StealEmojiPolicy: Failed to fetch #{url}: #{inspect(e)}")
- nil
end
@impl true
def filter(%{"object" => %{"emoji" => foreign_emojis, "actor" => actor}} = message) do
host = URI.parse(actor).host
- if remote_host?(host) and accept_host?(host) do
+ if host != Pleroma.Web.Endpoint.host() and accept_host?(host) do
installed_emoji = Pleroma.Emoji.get_all() |> Enum.map(fn {k, _} -> k end)
+ emoji_dir_path =
+ Config.get(
+ [:mrf_steal_emoji, :path],
+ Path.join(Config.get([:instance, :static_dir]), "emoji/stolen")
+ )
+
+ File.mkdir_p(emoji_dir_path)
+
new_emojis =
foreign_emojis
- |> Enum.filter(fn {shortcode, _url} -> shortcode not in installed_emoji end)
+ |> Enum.reject(fn {shortcode, _url} -> shortcode in installed_emoji end)
|> Enum.filter(fn {shortcode, _url} ->
reject_emoji? =
- Config.get([:mrf_steal_emoji, :rejected_shortcodes], [])
+ [:mrf_steal_emoji, :rejected_shortcodes]
+ |> Config.get([])
|> Enum.find(false, fn regex -> String.match?(shortcode, regex) end)
!reject_emoji?
end)
- |> Enum.map(&steal_emoji(&1))
+ |> Enum.map(&steal_emoji(&1, emoji_dir_path))
|> Enum.filter(& &1)
if !Enum.empty?(new_emojis) do
diff --git a/lib/pleroma/web/pleroma_api/views/backup_view.ex b/lib/pleroma/web/pleroma_api/views/backup_view.ex
index af75876aa..39affe979 100644
--- a/lib/pleroma/web/pleroma_api/views/backup_view.ex
+++ b/lib/pleroma/web/pleroma_api/views/backup_view.ex
@@ -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,
diff --git a/lib/pleroma/web/plugs/uploaded_media.ex b/lib/pleroma/web/plugs/uploaded_media.ex
index 402a8bb34..94b4c2177 100644
--- a/lib/pleroma/web/plugs/uploaded_media.ex
+++ b/lib/pleroma/web/plugs/uploaded_media.ex
@@ -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
diff --git a/priv/repo/migrations/20201231185546_confirm_logged_in_users.exs b/priv/repo/migrations/20201231185546_confirm_logged_in_users.exs
new file mode 100644
index 000000000..de2f35169
--- /dev/null
+++ b/priv/repo/migrations/20201231185546_confirm_logged_in_users.exs
@@ -0,0 +1,22 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Repo.Migrations.ConfirmLoggedInUsers do
+ use Ecto.Migration
+ import Ecto.Query
+ alias Pleroma.Repo
+ alias Pleroma.User
+ alias Pleroma.Web.OAuth.Token
+
+ def up do
+ User
+ |> where([u], u.confirmation_pending == true)
+ |> join(:inner, [u], t in Token, on: t.user_id == u.id)
+ |> Repo.update_all(set: [confirmation_pending: false])
+ end
+
+ def down do
+ :noop
+ end
+end
diff --git a/test/pleroma/repo/migrations/confirm_logged_in_users_test.exs b/test/pleroma/repo/migrations/confirm_logged_in_users_test.exs
new file mode 100644
index 000000000..f1fd89113
--- /dev/null
+++ b/test/pleroma/repo/migrations/confirm_logged_in_users_test.exs
@@ -0,0 +1,40 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Repo.Migrations.ConfirmLoggedInUsersTest do
+ alias Pleroma.Repo
+ alias Pleroma.User
+ use Pleroma.DataCase, async: true
+ import Ecto.Query
+ import Pleroma.Factory
+ import Pleroma.Tests.Helpers
+
+ setup_all do: require_migration("20201231185546_confirm_logged_in_users")
+
+ test "up/0 confirms unconfirmed but previously-logged-in users", %{migration: migration} do
+ insert_list(25, :oauth_token)
+ Repo.update_all(User, set: [confirmation_pending: true])
+ insert_list(5, :user, confirmation_pending: true)
+
+ count =
+ User
+ |> where(confirmation_pending: true)
+ |> Repo.aggregate(:count)
+
+ assert count == 30
+
+ assert {25, nil} == migration.up()
+
+ count =
+ User
+ |> where(confirmation_pending: true)
+ |> Repo.aggregate(:count)
+
+ assert count == 5
+ end
+
+ test "down/0 does nothing", %{migration: migration} do
+ assert :noop == migration.down()
+ end
+end
diff --git a/test/pleroma/web/activity_pub/mrf/steal_emoji_policy_test.exs b/test/pleroma/web/activity_pub/mrf/steal_emoji_policy_test.exs
index 3f8222736..7665d00d0 100644
--- a/test/pleroma/web/activity_pub/mrf/steal_emoji_policy_test.exs
+++ b/test/pleroma/web/activity_pub/mrf/steal_emoji_policy_test.exs
@@ -6,6 +6,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.StealEmojiPolicyTest do
use Pleroma.DataCase
alias Pleroma.Config
+ alias Pleroma.Emoji
alias Pleroma.Web.ActivityPub.MRF.StealEmojiPolicy
setup_all do
@@ -14,22 +15,9 @@ defmodule Pleroma.Web.ActivityPub.MRF.StealEmojiPolicyTest do
end
setup do
- emoji_path = Path.join(Config.get([:instance, :static_dir]), "emoji/stolen")
- File.rm_rf!(emoji_path)
- File.mkdir!(emoji_path)
+ emoji_path = [:instance, :static_dir] |> Config.get() |> Path.join("emoji/stolen")
- Pleroma.Emoji.reload()
-
- on_exit(fn ->
- File.rm_rf!(emoji_path)
- end)
-
- :ok
- end
-
- test "does nothing by default" do
- installed_emoji = Pleroma.Emoji.get_all() |> Enum.map(fn {k, _} -> k end)
- refute "firedfox" in installed_emoji
+ Emoji.reload()
message = %{
"type" => "Create",
@@ -39,30 +27,79 @@ defmodule Pleroma.Web.ActivityPub.MRF.StealEmojiPolicyTest do
}
}
- assert {:ok, message} == StealEmojiPolicy.filter(message)
+ on_exit(fn ->
+ File.rm_rf!(emoji_path)
+ end)
- installed_emoji = Pleroma.Emoji.get_all() |> Enum.map(fn {k, _} -> k end)
- refute "firedfox" in installed_emoji
+ [message: message, path: emoji_path]
end
- test "Steals emoji on unknown shortcode from allowed remote host" do
- installed_emoji = Pleroma.Emoji.get_all() |> Enum.map(fn {k, _} -> k end)
- refute "firedfox" in installed_emoji
+ test "does nothing by default", %{message: message} do
+ refute "firedfox" in installed()
- message = %{
- "type" => "Create",
- "object" => %{
- "emoji" => [{"firedfox", "https://example.org/emoji/firedfox.png"}],
- "actor" => "https://example.org/users/admin"
- }
- }
+ assert {:ok, _message} = StealEmojiPolicy.filter(message)
+
+ refute "firedfox" in installed()
+ end
- clear_config([:mrf_steal_emoji, :hosts], ["example.org"])
- clear_config([:mrf_steal_emoji, :size_limit], 284_468)
+ test "Steals emoji on unknown shortcode from allowed remote host", %{
+ message: message,
+ path: path
+ } do
+ refute "firedfox" in installed()
+ refute File.exists?(path)
- assert {:ok, message} == StealEmojiPolicy.filter(message)
+ clear_config(:mrf_steal_emoji, hosts: ["example.org"], size_limit: 284_468)
- installed_emoji = Pleroma.Emoji.get_all() |> Enum.map(fn {k, _} -> k end)
- assert "firedfox" in installed_emoji
+ assert {:ok, _message} = StealEmojiPolicy.filter(message)
+
+ assert "firedfox" in installed()
+ assert File.exists?(path)
+
+ assert path
+ |> Path.join("firedfox.png")
+ |> File.exists?()
+ end
+
+ test "reject shortcode", %{message: message} do
+ refute "firedfox" in installed()
+
+ clear_config(:mrf_steal_emoji,
+ hosts: ["example.org"],
+ size_limit: 284_468,
+ rejected_shortcodes: [~r/firedfox/]
+ )
+
+ assert {:ok, _message} = StealEmojiPolicy.filter(message)
+
+ refute "firedfox" in installed()
+ end
+
+ test "reject if size is above the limit", %{message: message} do
+ refute "firedfox" in installed()
+
+ clear_config(:mrf_steal_emoji, hosts: ["example.org"], size_limit: 50_000)
+
+ assert {:ok, _message} = StealEmojiPolicy.filter(message)
+
+ refute "firedfox" in installed()
+ end
+
+ test "reject if host returns error", %{message: message} do
+ refute "firedfox" in installed()
+
+ Tesla.Mock.mock(fn %{method: :get, url: "https://example.org/emoji/firedfox.png"} ->
+ {:ok, %Tesla.Env{status: 404, body: "Not found"}}
+ end)
+
+ clear_config(:mrf_steal_emoji, hosts: ["example.org"], size_limit: 284_468)
+
+ ExUnit.CaptureLog.capture_log(fn ->
+ assert {:ok, _message} = StealEmojiPolicy.filter(message)
+ end) =~ "MRF.StealEmojiPolicy: Failed to fetch https://example.org/emoji/firedfox.png"
+
+ refute "firedfox" in installed()
end
+
+ defp installed, do: Emoji.get_all() |> Enum.map(fn {k, _} -> k end)
end
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
index 000000000..7dda8480b
--- /dev/null
+++ b/test/pleroma/web/pleroma_api/views/backup_view_test.exs
@@ -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