aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhref <href@random.sh>2019-01-21 22:44:14 +0100
committerhref <href@random.sh>2019-01-21 22:44:14 +0100
commitf9a326909979959d6cb43f66177045bb2adccbf4 (patch)
treee522bd8575764287798f070c6cfcf7b5a812cace
parentafb8d9ec134b9c12a116da27e4c6da7f3e9941a6 (diff)
downloadpleroma-f9a326909979959d6cb43f66177045bb2adccbf4.tar.gz
Uploader callback controller
-rw-r--r--lib/pleroma/uploaders/uploader.ex37
-rw-r--r--lib/pleroma/web/router.ex5
-rw-r--r--lib/pleroma/web/uploader_controller.ex25
3 files changed, 63 insertions, 4 deletions
diff --git a/lib/pleroma/uploaders/uploader.ex b/lib/pleroma/uploaders/uploader.ex
index 0959d7a3e..ce83cbbbc 100644
--- a/lib/pleroma/uploaders/uploader.ex
+++ b/lib/pleroma/uploaders/uploader.ex
@@ -27,18 +27,47 @@ defmodule Pleroma.Uploaders.Uploader do
This allows to correctly proxy or redirect requests to the backend, while allowing to migrate backends without breaking any URL.
* `{url, url :: String.t}` to bypass `get_file/2` and use the `url` directly in the activity.
* `{:error, String.t}` error information if the file failed to be saved to the backend.
+ * `:wait_callback` will wait for an http post request at `/api/pleroma/upload_callback/:upload_path` and call the uploader's `http_callback/3` method.
"""
+ @type file_spec :: {:file | :url, String.t()}
@callback put_file(Pleroma.Upload.t()) ::
- :ok | {:ok, {:file | :url, String.t()}} | {:error, String.t()}
+ :ok | {:ok, file_spec()} | {:error, String.t()} | :wait_callback
+
+ @callback http_callback(Plug.Conn.t(), Map.t()) ::
+ {:ok, Plug.Conn.t()}
+ | {:ok, Plug.Conn.t(), file_spec()}
+ | {:error, Plug.Conn.t(), String.t()}
+ @optional_callbacks http_callback: 2
+
+ @spec put_file(module(), Pleroma.Upload.t()) :: {:ok, file_spec()} | {:error, String.t()}
- @spec put_file(module(), Pleroma.Upload.t()) ::
- {:ok, {:file | :url, String.t()}} | {:error, String.t()}
def put_file(uploader, upload) do
case uploader.put_file(upload) do
:ok -> {:ok, {:file, upload.path}}
- other -> other
+ :wait_callback -> handle_callback(uploader, upload)
+ {:ok, _} = ok -> ok
+ {:error, _} = error -> error
+ end
+ end
+
+ defp handle_callback(uploader, upload) do
+ :global.register_name({__MODULE__, upload.path}, self())
+
+ receive do
+ {__MODULE__, pid, conn, params} ->
+ case uploader.http_callback(conn, params) do
+ {:ok, conn, ok} ->
+ send(pid, {__MODULE__, conn})
+ {:ok, ok}
+
+ {:error, conn, error} ->
+ send(pid, {__MODULE__, conn})
+ {:error, error}
+ end
+ after
+ 30_000 -> {:error, "Uploader callback timeout"}
end
end
end
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index 7a0c9fd25..69ab58c6a 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -107,6 +107,11 @@ defmodule Pleroma.Web.Router do
get("/captcha", UtilController, :captcha)
end
+ scope "/api/pleroma", Pleroma.Web do
+ pipe_through(:pleroma_api)
+ post("/uploader_callback/:upload_path", UploaderController, :callback)
+ end
+
scope "/api/pleroma/admin", Pleroma.Web.AdminAPI do
pipe_through(:admin_api)
delete("/user", AdminAPIController, :user_delete)
diff --git a/lib/pleroma/web/uploader_controller.ex b/lib/pleroma/web/uploader_controller.ex
new file mode 100644
index 000000000..6c28d1197
--- /dev/null
+++ b/lib/pleroma/web/uploader_controller.ex
@@ -0,0 +1,25 @@
+defmodule Pleroma.Web.UploaderController do
+ use Pleroma.Web, :controller
+
+ alias Pleroma.Uploaders.Uploader
+
+ def callback(conn, params = %{"upload_path" => upload_path}) do
+ process_callback(conn, :global.whereis_name({Uploader, upload_path}), params)
+ end
+
+ def callbacks(conn, _) do
+ send_resp(conn, 400, "bad request")
+ end
+
+ defp process_callback(conn, pid, params) when is_pid(pid) do
+ send(pid, {Uploader, self(), conn, params})
+
+ receive do
+ {Uploader, conn} -> conn
+ end
+ end
+
+ defp process_callback(conn, _, _) do
+ send_resp(conn, 400, "bad request")
+ end
+end