Fork of Pleroma with site-specific changes and feature branches https://git.pleroma.social/pleroma/pleroma
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

100 行
2.8KB

  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Web.ActivityPub.MRF.StealEmojiPolicy do
  5. require Logger
  6. alias Pleroma.Config
  7. @moduledoc "Detect new emojis by their shortcode and steals them"
  8. @behaviour Pleroma.Web.ActivityPub.MRF.Policy
  9. defp accept_host?(host), do: host in Config.get([:mrf_steal_emoji, :hosts], [])
  10. defp steal_emoji({shortcode, url}, emoji_dir_path) do
  11. url = Pleroma.Web.MediaProxy.url(url)
  12. with {:ok, %{status: status} = response} when status in 200..299 <- Pleroma.HTTP.get(url) do
  13. size_limit = Config.get([:mrf_steal_emoji, :size_limit], 50_000)
  14. if byte_size(response.body) <= size_limit do
  15. extension =
  16. url
  17. |> URI.parse()
  18. |> Map.get(:path)
  19. |> Path.basename()
  20. |> Path.extname()
  21. file_path = Path.join(emoji_dir_path, shortcode <> (extension || ".png"))
  22. case File.write(file_path, response.body) do
  23. :ok ->
  24. shortcode
  25. e ->
  26. Logger.warn("MRF.StealEmojiPolicy: Failed to write to #{file_path}: #{inspect(e)}")
  27. nil
  28. end
  29. else
  30. Logger.debug(
  31. "MRF.StealEmojiPolicy: :#{shortcode}: at #{url} (#{byte_size(response.body)} B) over size limit (#{
  32. size_limit
  33. } B)"
  34. )
  35. nil
  36. end
  37. else
  38. e ->
  39. Logger.warn("MRF.StealEmojiPolicy: Failed to fetch #{url}: #{inspect(e)}")
  40. nil
  41. end
  42. end
  43. @impl true
  44. def filter(%{"object" => %{"emoji" => foreign_emojis, "actor" => actor}} = message) do
  45. host = URI.parse(actor).host
  46. if host != Pleroma.Web.Endpoint.host() and accept_host?(host) do
  47. installed_emoji = Pleroma.Emoji.get_all() |> Enum.map(fn {k, _} -> k end)
  48. emoji_dir_path =
  49. Config.get(
  50. [:mrf_steal_emoji, :path],
  51. Path.join(Config.get([:instance, :static_dir]), "emoji/stolen")
  52. )
  53. File.mkdir_p(emoji_dir_path)
  54. new_emojis =
  55. foreign_emojis
  56. |> Enum.reject(fn {shortcode, _url} -> shortcode in installed_emoji end)
  57. |> Enum.filter(fn {shortcode, _url} ->
  58. reject_emoji? =
  59. [:mrf_steal_emoji, :rejected_shortcodes]
  60. |> Config.get([])
  61. |> Enum.find(false, fn regex -> String.match?(shortcode, regex) end)
  62. !reject_emoji?
  63. end)
  64. |> Enum.map(&steal_emoji(&1, emoji_dir_path))
  65. |> Enum.filter(& &1)
  66. if !Enum.empty?(new_emojis) do
  67. Logger.info("Stole new emojis: #{inspect(new_emojis)}")
  68. Pleroma.Emoji.reload()
  69. end
  70. end
  71. {:ok, message}
  72. end
  73. def filter(message), do: {:ok, message}
  74. @impl true
  75. def describe do
  76. {:ok, %{}}
  77. end
  78. end