Previewing proxy proof of concept

This commit is contained in:
lain 2020-01-30 19:16:15 +01:00
parent a0d9d42eaa
commit 57b8258ca9
4 changed files with 64 additions and 1 deletions

View File

@ -358,6 +358,7 @@ def render("attachment.json", %{attachment: attachment}) do
[attachment_url | _] = attachment["url"]
media_type = attachment_url["mediaType"] || attachment_url["mimeType"] || "image"
href = attachment_url["href"] |> MediaProxy.url()
href_preview = attachment_url["href"] |> MediaProxy.preview_url()
type =
cond do
@ -373,7 +374,7 @@ def render("attachment.json", %{attachment: attachment}) do
id: to_string(attachment["id"] || hash_id),
url: href,
remote_url: href,
preview_url: href,
preview_url: href_preview,
text_url: href,
type: type,
description: attachment["name"],

View File

@ -20,6 +20,14 @@ def url(url) do
end
end
def preview_url(url) do
if disabled?() or whitelisted?(url) do
url
else
encode_preview_url(url)
end
end
defp disabled?, do: !Config.get([:media_proxy, :enabled], false)
defp local?(url), do: String.starts_with?(url, Pleroma.Web.base_url())
@ -54,6 +62,17 @@ def encode_url(url) do
build_url(sig64, base64, filename(url))
end
def encode_preview_url(url) do
base64 = Base.url_encode64(url, @base64_opts)
sig64 =
base64
|> signed_url
|> Base.url_encode64(@base64_opts)
build_preview_url(sig64, base64, filename(url))
end
def decode_url(sig, url) do
with {:ok, sig} <- Base.url_decode64(sig, @base64_opts),
signature when signature == sig <- signed_url(url) do
@ -82,4 +101,17 @@ def build_url(sig_base64, url_base64, filename \\ nil) do
|> Enum.filter(& &1)
|> Path.join()
end
def build_preview_url(sig_base64, url_base64, filename \\ nil) do
[
Pleroma.Config.get([:media_proxy, :base_url], Web.base_url()),
"proxy",
"preview",
sig_base64,
url_base64,
filename
]
|> Enum.filter(& &1)
|> Path.join()
end
end

View File

@ -27,6 +27,33 @@ def remote(conn, %{"sig" => sig64, "url" => url64} = params) do
end
end
def preview(conn, %{"sig" => sig64, "url" => url64} = params) do
with config <- Pleroma.Config.get([:media_proxy], []),
true <- Keyword.get(config, :enabled, false),
{:ok, url} <- MediaProxy.decode_url(sig64, url64),
:ok <- filename_matches(params, conn.request_path, url),
{:ok, %{body: body}} = _tesla <- Tesla.get(url) do
path = Mogrify.temporary_path_for(%{path: url})
File.write!(path, body)
Mogrify.open(path)
|> Mogrify.resize_to_limit("400x200")
|> Mogrify.save(in_place: true)
conn
|> send_file(200, path)
else
false ->
send_resp(conn, 404, Plug.Conn.Status.reason_phrase(404))
{:error, :invalid_signature} ->
send_resp(conn, 403, Plug.Conn.Status.reason_phrase(403))
{:wrong_filename, filename} ->
redirect(conn, external: MediaProxy.build_url(sig64, url64, filename))
end
end
def filename_matches(%{"filename" => _} = _, path, url) do
filename = MediaProxy.filename(url)

View File

@ -640,6 +640,9 @@ defmodule Pleroma.Web.Router do
scope "/proxy/", Pleroma.Web.MediaProxy do
pipe_through(:remote_media)
get("/preview/:sig/:url", MediaProxyController, :preview)
get("/preview/:sig/:url/:filename", MediaProxyController, :preview)
get("/:sig/:url", MediaProxyController, :remote)
get("/:sig/:url/:filename", MediaProxyController, :remote)
end