2020-03-22 18:05:39 +00:00
|
|
|
# SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
2020-03-22 16:41:29 +00:00
|
|
|
defmodule Pleroma.Web.ActivityPub.MRF.StealEmojiPolicy do
|
|
|
|
require Logger
|
|
|
|
@moduledoc "Detect new emoji and steal them"
|
|
|
|
@behaviour Pleroma.Web.ActivityPub.MRF
|
|
|
|
|
|
|
|
defp has_emojo(installed_emoji, str) do
|
|
|
|
result = for emojo <- installed_emoji, elem(emojo, 0) == str, do: true
|
|
|
|
length(result) == 1
|
|
|
|
end
|
|
|
|
|
2020-03-23 01:01:30 +00:00
|
|
|
defp is_remote(host) do
|
|
|
|
my_host = Pleroma.Config.get([Pleroma.Web.Endpoint, :url, :host])
|
|
|
|
my_host != host
|
|
|
|
end
|
|
|
|
|
|
|
|
# if whitelist is not defined, everything is "whitelisted"
|
|
|
|
defp is_whitelisted(domain) do
|
|
|
|
whitelist = Pleroma.Config.get([:emoji_stealer, :whitelist])
|
|
|
|
|
|
|
|
whitelist == nil || Enum.member?(whitelist, domain)
|
2020-03-22 21:41:17 +00:00
|
|
|
end
|
|
|
|
|
2020-03-22 16:41:29 +00:00
|
|
|
@impl true
|
2020-03-22 21:41:17 +00:00
|
|
|
def filter(%{"object" => %{"emoji" => foreign_emoji, "actor" => actor}} = object) do
|
2020-03-23 01:01:30 +00:00
|
|
|
host = URI.parse(actor).host
|
|
|
|
|
|
|
|
if is_remote(host) && is_whitelisted(host) do
|
2020-03-22 21:41:17 +00:00
|
|
|
num_foreign_emoji = Kernel.map_size(foreign_emoji)
|
|
|
|
|
|
|
|
if num_foreign_emoji > 0 do
|
|
|
|
Logger.debug("#{num_foreign_emoji} EMOJI TO PROCESS")
|
|
|
|
installed_emoji = Pleroma.Emoji.get_all()
|
|
|
|
|
|
|
|
new_files =
|
|
|
|
for {emojo_shortcode, emojo_url} <- foreign_emoji,
|
|
|
|
!has_emojo(installed_emoji, emojo_shortcode) do
|
2020-03-24 02:33:27 +00:00
|
|
|
Logger.debug("HANDLING EMOJO #{emojo_shortcode} #{emojo_url}")
|
2020-03-22 21:41:17 +00:00
|
|
|
|
|
|
|
cond do
|
2020-03-24 00:12:42 +00:00
|
|
|
!String.match?(emojo_shortcode, ~r/^[[:word:]]+$/) ->
|
2020-03-22 21:41:17 +00:00
|
|
|
Logger.error("BAD EMOJO SHORTCODE: #{emojo_shortcode}")
|
|
|
|
|
|
|
|
String.starts_with?(emojo_url, "https://") ->
|
|
|
|
try do
|
|
|
|
remote_emojo = HTTPoison.get!(emojo_url)
|
|
|
|
|
|
|
|
if remote_emojo.status_code == 200 do
|
2020-03-24 02:33:27 +00:00
|
|
|
Logger.debug("got remote emoji")
|
|
|
|
emoji_dir_path = Path.join(Pleroma.Config.get!([:instance, :static_dir]), "emoji/stolen")
|
2020-03-24 01:01:37 +00:00
|
|
|
|
|
|
|
emojo_uri = URI.parse(emojo_url)
|
|
|
|
extension = Path.extname(Path.basename(emojo_uri.path))
|
|
|
|
filename = emojo_shortcode <> extension
|
|
|
|
|
2020-03-24 02:33:27 +00:00
|
|
|
new_file = Path.join([emoji_dir_path, filename])
|
2020-03-24 01:01:37 +00:00
|
|
|
|
|
|
|
{:ok, file} = File.open(new_file, [:write])
|
|
|
|
IO.binwrite(file, remote_emojo.body)
|
|
|
|
File.close(file)
|
|
|
|
Logger.debug("SAVED EMOJO")
|
|
|
|
new_file
|
2020-03-22 17:47:45 +00:00
|
|
|
end
|
2020-03-22 21:41:17 +00:00
|
|
|
rescue
|
|
|
|
e in RuntimeError -> Logger.error("FAILED TO QUERY REMOTE EMOJO #{emojo_url} #{e}")
|
2020-03-22 17:47:45 +00:00
|
|
|
end
|
|
|
|
|
2020-03-22 21:41:17 +00:00
|
|
|
true ->
|
|
|
|
Logger.error("EMOJO COND FAIL #{emojo_shortcode} #{emojo_url}")
|
|
|
|
end
|
|
|
|
|
2020-03-22 17:47:45 +00:00
|
|
|
|
2020-03-22 21:41:17 +00:00
|
|
|
end
|
2020-03-22 16:41:29 +00:00
|
|
|
|
2020-03-22 21:41:17 +00:00
|
|
|
Logger.debug("EMOJI FILES: #{inspect(new_files)}")
|
2020-03-22 16:41:29 +00:00
|
|
|
|
2020-03-22 21:41:17 +00:00
|
|
|
if length(new_files) > 0 do
|
|
|
|
Logger.debug("RELOADING EMOJI")
|
|
|
|
Pleroma.Emoji.reload()
|
|
|
|
else
|
|
|
|
Logger.debug("NO EMOJI TO LOAD")
|
|
|
|
end
|
2020-03-22 16:41:29 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
{:ok, object}
|
|
|
|
end
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
def filter(object) do
|
|
|
|
{:ok, object}
|
|
|
|
end
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
def describe, do: {:ok, %{}}
|
|
|
|
end
|