From cfc8d7aade526b8f119683984977064cd3cd3d87 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Tue, 28 May 2024 13:14:34 -0400 Subject: [PATCH] IPFS uploader: dialyzer fixes lib/pleroma/uploaders/ipfs.ex:43:no_return Function put_file/1 has no local return. ________________________________________________________________________________ lib/pleroma/uploaders/ipfs.ex:49:call The function call will not succeed. Pleroma.HTTP.post( binary(), _mp :: %Tesla.Multipart{ :boundary => binary(), :content_type_params => [binary()], :parts => [ %Tesla.Multipart.Part{ :body => binary(), :dispositions => [any()], :headers => [any()] }, ... ] }, [], [{:params, [{:"cid-version", <<49>>}]}] ) will never return since the success typing is: (binary(), binary(), [{binary(), binary()}], Keyword.t()) :: {:error, _} | {:ok, %Tesla.Env{ :__client__ => %Tesla.Client{ :adapter => nil | {_, _} | {_, _, _}, :fun => _, :post => [any()], :pre => [any()] }, :__module__ => atom(), :body => _, :headers => [{_, _}], :method => :delete | :get | :head | :options | :patch | :post | :put | :trace, :opts => [{_, _}], :query => [{_, _}], :status => nil | integer(), :url => binary() }} and the contract is (Pleroma.HTTP.Request.url(), String.t(), Pleroma.HTTP.Request.headers(), :elixir.keyword()) :: {:ok, Tesla.Env.t()} | {:error, any()} --- changelog.d/ipfs-dialyzer.skip | 1 + config/config.exs | 4 +- lib/pleroma/http.ex | 4 +- lib/pleroma/uploaders/ipfs.ex | 57 +++++++++++++--------------- test/pleroma/uploaders/ipfs_test.exs | 51 ++++++++++++------------- 5 files changed, 55 insertions(+), 62 deletions(-) create mode 100644 changelog.d/ipfs-dialyzer.skip diff --git a/changelog.d/ipfs-dialyzer.skip b/changelog.d/ipfs-dialyzer.skip new file mode 100644 index 000000000..b3e74cd19 --- /dev/null +++ b/changelog.d/ipfs-dialyzer.skip @@ -0,0 +1 @@ +no comment diff --git a/config/config.exs b/config/config.exs index c3b8ae0b7..a40ed28af 100644 --- a/config/config.exs +++ b/config/config.exs @@ -83,8 +83,8 @@ config :ex_aws, :s3, scheme: "https://" config :pleroma, Pleroma.Uploaders.IPFS, - post_gateway_url: nil, - get_gateway_url: nil + post_gateway_url: "http://localhost:5001", + get_gateway_url: "http://localhost:8080" config :pleroma, :emoji, shortcode_globs: ["/emoji/custom/**/*.png"], diff --git a/lib/pleroma/http.ex b/lib/pleroma/http.ex index eec61cf14..ec837e509 100644 --- a/lib/pleroma/http.ex +++ b/lib/pleroma/http.ex @@ -37,7 +37,7 @@ defmodule Pleroma.HTTP do See `Pleroma.HTTP.request/5` """ - @spec post(Request.url(), String.t(), Request.headers(), keyword()) :: + @spec post(Request.url(), Tesla.Env.body(), Request.headers(), keyword()) :: {:ok, Env.t()} | {:error, any()} def post(url, body, headers \\ [], options \\ []), do: request(:post, url, body, headers, options) @@ -56,7 +56,7 @@ defmodule Pleroma.HTTP do `{:ok, %Tesla.Env{}}` or `{:error, error}` """ - @spec request(method(), Request.url(), String.t(), Request.headers(), keyword()) :: + @spec request(method(), Request.url(), Tesla.Env.body(), Request.headers(), keyword()) :: {:ok, Env.t()} | {:error, any()} def request(method, url, body, headers, options) when is_binary(url) do uri = URI.parse(url) diff --git a/lib/pleroma/uploaders/ipfs.ex b/lib/pleroma/uploaders/ipfs.ex index d171e4652..5930a129e 100644 --- a/lib/pleroma/uploaders/ipfs.ex +++ b/lib/pleroma/uploaders/ipfs.ex @@ -8,23 +8,10 @@ defmodule Pleroma.Uploaders.IPFS do alias Tesla.Multipart + @api_add "/api/v0/add" + @api_delete "/api/v0/files/rm" @config_impl Application.compile_env(:pleroma, [__MODULE__, :config_impl], Pleroma.Config) - defp get_final_url(method) do - config = @config_impl.get([__MODULE__]) - post_base_url = Keyword.get(config, :post_gateway_url) - - Path.join([post_base_url, method]) - end - - def put_file_endpoint do - get_final_url("/api/v0/add") - end - - def delete_file_endpoint do - get_final_url("/api/v0/files/rm") - end - @placeholder "{CID}" def placeholder, do: @placeholder @@ -40,26 +27,26 @@ defmodule Pleroma.Uploaders.IPFS do end @impl true - def put_file(%Pleroma.Upload{} = upload) do + def put_file(%Pleroma.Upload{tempfile: tempfile}) do mp = Multipart.new() |> Multipart.add_content_type_param("charset=utf-8") - |> Multipart.add_file(upload.tempfile) + |> Multipart.add_file(tempfile) - case Pleroma.HTTP.post(put_file_endpoint(), mp, [], params: ["cid-version": "1"]) do - {:ok, ret} -> - case Jason.decode(ret.body) do - {:ok, ret} -> - if Map.has_key?(ret, "Hash") do - {:ok, {:file, ret["Hash"]}} - else - {:error, "JSON doesn't contain Hash key"} - end + endpoint = ipfs_endpoint(@api_add) - error -> - Logger.error("#{__MODULE__}: #{inspect(error)}") - {:error, "JSON decode failed"} - end + with {:ok, %{body: body}} when is_binary(body) <- + Pleroma.HTTP.post(endpoint, mp, [], params: ["cid-version": "1"], pool: :upload), + {_, {:ok, decoded}} <- {:json, Jason.decode(body)}, + {_, true} <- {:hash, Map.has_key?(decoded, "Hash")} do + {:ok, {:file, decoded["Hash"]}} + else + {:hash, false} -> + {:error, "JSON doesn't contain Hash key"} + + {:json, error} -> + Logger.error("#{__MODULE__}: #{inspect(error)}") + {:error, "JSON decode failed"} error -> Logger.error("#{__MODULE__}: #{inspect(error)}") @@ -69,9 +56,17 @@ defmodule Pleroma.Uploaders.IPFS do @impl true def delete_file(file) do - case Pleroma.HTTP.post(delete_file_endpoint(), "", [], params: [arg: file]) do + endpoint = ipfs_endpoint(@api_delete) + + case Pleroma.HTTP.post(endpoint, "", [], params: [arg: file]) do {:ok, %{status: 204}} -> :ok error -> {:error, inspect(error)} end end + + defp ipfs_endpoint(path) do + URI.parse(@config_impl.get([__MODULE__, :post_gateway_url])) + |> Map.put(:path, path) + |> URI.to_string() + end end diff --git a/test/pleroma/uploaders/ipfs_test.exs b/test/pleroma/uploaders/ipfs_test.exs index cf325b54f..bdf2933ac 100644 --- a/test/pleroma/uploaders/ipfs_test.exs +++ b/test/pleroma/uploaders/ipfs_test.exs @@ -14,25 +14,6 @@ defmodule Pleroma.Uploaders.IPFSTest do alias Pleroma.UnstubbedConfigMock, as: Config - describe "get_final_url" do - setup do - Config - |> expect(:get, fn [Pleroma.Uploaders.IPFS] -> - [post_gateway_url: "http://localhost:5001"] - end) - - :ok - end - - test "it returns the final url for put_file" do - assert IPFS.put_file_endpoint() == "http://localhost:5001/api/v0/add" - end - - test "it returns the final url for delete_file" do - assert IPFS.delete_file_endpoint() == "http://localhost:5001/api/v0/files/rm" - end - end - describe "get_file/1" do setup do Config @@ -71,8 +52,8 @@ defmodule Pleroma.Uploaders.IPFSTest do describe "put_file/1" do setup do Config - |> expect(:get, fn [Pleroma.Uploaders.IPFS] -> - [post_gateway_url: "http://localhost:5001"] + |> expect(:get, fn [Pleroma.Uploaders.IPFS, :post_gateway_url] -> + "http://localhost:5001" end) file_upload = %Pleroma.Upload{ @@ -92,7 +73,11 @@ defmodule Pleroma.Uploaders.IPFSTest do test "save file", %{file_upload: file_upload} do with_mock Pleroma.HTTP, - post: fn "http://localhost:5001/api/v0/add", _mp, [], params: ["cid-version": "1"] -> + post: fn "http://localhost:5001/api/v0/add", + _mp, + [], + params: ["cid-version": "1"], + pool: :upload -> {:ok, %Tesla.Env{ status: 200, @@ -107,7 +92,11 @@ defmodule Pleroma.Uploaders.IPFSTest do test "returns error", %{file_upload: file_upload} do with_mock Pleroma.HTTP, - post: fn "http://localhost:5001/api/v0/add", _mp, [], params: ["cid-version": "1"] -> + post: fn "http://localhost:5001/api/v0/add", + _mp, + [], + params: ["cid-version": "1"], + pool: :upload -> {:error, "IPFS Gateway upload failed"} end do assert capture_log(fn -> @@ -118,7 +107,11 @@ defmodule Pleroma.Uploaders.IPFSTest do test "returns error if JSON decode fails", %{file_upload: file_upload} do with_mock Pleroma.HTTP, [], - post: fn "http://localhost:5001/api/v0/add", _mp, [], params: ["cid-version": "1"] -> + post: fn "http://localhost:5001/api/v0/add", + _mp, + [], + params: ["cid-version": "1"], + pool: :upload -> {:ok, %Tesla.Env{status: 200, body: "invalid"}} end do assert capture_log(fn -> @@ -130,7 +123,11 @@ defmodule Pleroma.Uploaders.IPFSTest do test "returns error if JSON body doesn't contain Hash key", %{file_upload: file_upload} do with_mock Pleroma.HTTP, [], - post: fn "http://localhost:5001/api/v0/add", _mp, [], params: ["cid-version": "1"] -> + post: fn "http://localhost:5001/api/v0/add", + _mp, + [], + params: ["cid-version": "1"], + pool: :upload -> {:ok, %Tesla.Env{status: 200, body: "{\"key\": \"value\"}"}} end do assert IPFS.put_file(file_upload) == {:error, "JSON doesn't contain Hash key"} @@ -141,8 +138,8 @@ defmodule Pleroma.Uploaders.IPFSTest do describe "delete_file/1" do setup do Config - |> expect(:get, fn [Pleroma.Uploaders.IPFS] -> - [post_gateway_url: "http://localhost:5001"] + |> expect(:get, fn [Pleroma.Uploaders.IPFS, :post_gateway_url] -> + "http://localhost:5001" end) :ok