forked from AkkomaGang/akkoma
Convert StealEmoji to pack.json
This will decouple filenames from shortcodes and allow more image formats to work instead of only those included in the auto-load glob. (Albeit we still saved other formats to disk, wasting space) Furthermore, this will allow us to make final URL paths infeasible to predict.
This commit is contained in:
parent
fa98b44acf
commit
d1c4d07404
2 changed files with 56 additions and 18 deletions
|
@ -92,7 +92,7 @@ defp unpack_zip_emojies(zip_files) do
|
|||
end)
|
||||
end
|
||||
|
||||
@spec add_file(t(), String.t(), Path.t(), Plug.Upload.t()) ::
|
||||
@spec add_file(t(), String.t(), Path.t(), Plug.Upload.t() | binary()) ::
|
||||
{:ok, t()}
|
||||
| {:error, File.posix() | atom()}
|
||||
def add_file(%Pack{} = pack, _, _, %Plug.Upload{content_type: "application/zip"} = file) do
|
||||
|
@ -140,6 +140,14 @@ def add_file(%Pack{} = pack, _, _, %Plug.Upload{content_type: "application/zip"}
|
|||
end
|
||||
|
||||
def add_file(%Pack{} = pack, shortcode, filename, %Plug.Upload{} = file) do
|
||||
try_add_file(pack, shortcode, filename, file)
|
||||
end
|
||||
|
||||
def add_file(%Pack{} = pack, shortcode, filename, filedata) when is_binary(filedata) do
|
||||
try_add_file(pack, shortcode, filename, filedata)
|
||||
end
|
||||
|
||||
defp try_add_file(%Pack{} = pack, shortcode, filename, file) do
|
||||
with :ok <- validate_not_empty([shortcode, filename]),
|
||||
:ok <- validate_emoji_not_exists(shortcode),
|
||||
{:ok, updated_pack} <- do_add_file(pack, shortcode, filename, file) do
|
||||
|
@ -485,6 +493,12 @@ defp save_file(%Plug.Upload{path: upload_path}, pack, filename) do
|
|||
end
|
||||
end
|
||||
|
||||
defp save_file(file_data, pack, filename) when is_binary(file_data) do
|
||||
file_path = Path.join(pack.path, filename)
|
||||
create_subdirs(file_path)
|
||||
File.write(file_path, file_data, [:binary])
|
||||
end
|
||||
|
||||
defp put_emoji(pack, shortcode, filename) do
|
||||
files = Map.put(pack.files, shortcode, filename)
|
||||
%{pack | files: files, files_count: length(Map.keys(files))}
|
||||
|
|
|
@ -6,10 +6,41 @@ defmodule Pleroma.Web.ActivityPub.MRF.StealEmojiPolicy do
|
|||
require Logger
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.Emoji.Pack
|
||||
|
||||
@moduledoc "Detect new emojis by their shortcode and steals them"
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
@pack_name "stolen"
|
||||
|
||||
defp create_pack() do
|
||||
with {:ok, pack} = Pack.create(@pack_name) do
|
||||
Pack.save_metadata(
|
||||
%{
|
||||
"description" => "Collection of emoji auto-stolen from other instances",
|
||||
"homepage" => Pleroma.Web.Endpoint.url(),
|
||||
"can-download" => false,
|
||||
"share-files" => false
|
||||
},
|
||||
pack
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
defp load_or_create_pack() do
|
||||
case Pack.load_pack(@pack_name) do
|
||||
{:ok, pack} -> {:ok, pack}
|
||||
{:error, :enoent} -> create_pack()
|
||||
e -> e
|
||||
end
|
||||
end
|
||||
|
||||
defp add_emoji(shortcode, extension, filedata) do
|
||||
{:ok, pack} = load_or_create_pack()
|
||||
filename = shortcode <> "." <> extension
|
||||
Pack.add_file(pack, shortcode, filename, filedata)
|
||||
end
|
||||
|
||||
defp accept_host?(host), do: host in Config.get([:mrf_steal_emoji, :hosts], [])
|
||||
|
||||
defp shortcode_matches?(shortcode, pattern) when is_binary(pattern) do
|
||||
|
@ -33,15 +64,16 @@ defp reject_emoji?({shortcode, _url}, installed_emoji) do
|
|||
!valid_shortcode? or rejected_shortcode? or emoji_installed?
|
||||
end
|
||||
|
||||
defp steal_emoji(%{} = response, {shortcode, extension}, emoji_dir_path) do
|
||||
file_path = Path.join(emoji_dir_path, shortcode <> "." <> extension)
|
||||
|
||||
case File.write(file_path, response.body) do
|
||||
:ok ->
|
||||
defp steal_emoji(%{} = response, {shortcode, extension}) do
|
||||
case add_emoji(shortcode, extension, response.body) do
|
||||
{:ok, _} ->
|
||||
shortcode
|
||||
|
||||
e ->
|
||||
Logger.warning("MRF.StealEmojiPolicy: Failed to write to #{file_path}: #{inspect(e)}")
|
||||
Logger.warning(
|
||||
"MRF.StealEmojiPolicy: Failed to add #{shortcode}.#{extension}: #{inspect(e)}"
|
||||
)
|
||||
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
@ -56,7 +88,7 @@ defp get_extension_if_safe(response) do
|
|||
end
|
||||
end
|
||||
|
||||
defp maybe_steal_emoji({shortcode, url}, emoji_dir_path) do
|
||||
defp maybe_steal_emoji({shortcode, url}) do
|
||||
url = Pleroma.Web.MediaProxy.url(url)
|
||||
|
||||
with {:ok, %{status: status} = response} when status in 200..299 <- Pleroma.HTTP.get(url) do
|
||||
|
@ -64,7 +96,7 @@ defp maybe_steal_emoji({shortcode, url}, emoji_dir_path) do
|
|||
extension = get_extension_if_safe(response)
|
||||
|
||||
if byte_size(response.body) <= size_limit and extension do
|
||||
steal_emoji(response, {shortcode, extension}, emoji_dir_path)
|
||||
steal_emoji(response, {shortcode, extension})
|
||||
else
|
||||
Logger.debug(
|
||||
"MRF.StealEmojiPolicy: :#{shortcode}: at #{url} (#{byte_size(response.body)} B) over size limit (#{size_limit} B)"
|
||||
|
@ -86,18 +118,10 @@ def filter(%{"object" => %{"emoji" => foreign_emojis, "actor" => actor}} = messa
|
|||
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.reject(&reject_emoji?(&1, installed_emoji))
|
||||
|> Enum.map(&maybe_steal_emoji(&1, emoji_dir_path))
|
||||
|> Enum.map(&maybe_steal_emoji(&1))
|
||||
|> Enum.filter(& &1)
|
||||
|
||||
if !Enum.empty?(new_emojis) do
|
||||
|
|
Loading…
Reference in a new issue