commit: 43dfa58ebda407a0813d398bee8d0ae3e5c9fd5b
parent fa2a6d5d6b24657ddbda4ef11d2e6dbcb59545d3
Author: Claudio Maradonna <penguyman@stronzi.org>
Date: Mon, 11 Apr 2022 15:10:01 +0200
added tests for ipfs uploader. adapted changelog.md accordingly. improved ipfs uploader with external suggestions
fix lint description.exs
Diffstat:
7 files changed, 116 insertions(+), 15 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
@@ -32,6 +32,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- PleromaAPI: Add `GET /api/v1/pleroma/birthdays` API endpoint
- Make backend-rendered pages translatable. This includes emails. Pages returned as a HTTP response are translated using the language specified in the `userLanguage` cookie, or the `Accept-Language` header. Emails are translated using the `language` field when registering. This language can be changed by `PATCH /api/v1/accounts/update_credentials` with the `language` field.
- Uploadfilter `Pleroma.Upload.Filter.Exiftool.ReadDescription` returns description values to the FE so they can pre fill the image description field
+- Uploader: Add support for uploading attachments using IPFS
### Fixed
- Subscription(Bell) Notifications: Don't create from Pipeline Ingested replies
diff --git a/config/description.exs b/config/description.exs
@@ -147,7 +147,8 @@ config :pleroma, :config_description, [
type: :string,
description: "GET Gateway URL",
suggestions: [
- "get_gateway_url"
+ "https://ipfs.mydomain.com/<%= cid %>",
+ "https://<%= cid %>.ipfs.mydomain.com/"
]
},
%{
@@ -155,7 +156,7 @@ config :pleroma, :config_description, [
type: :string,
description: "POST Gateway URL",
suggestions: [
- "post_gateway_url"
+ "http://localhost:5001/"
]
}
]
diff --git a/config/dev.exs b/config/dev.exs
@@ -58,10 +58,6 @@ config :pleroma, Pleroma.Web.ApiSpec.CastAndValidate, strict: true
# https://dashbit.co/blog/speeding-up-re-compilation-of-elixir-projects
config :phoenix, :plug_init_mode, :runtime
-config :pleroma, Pleroma.Uploaders.IPFS,
- post_gateway_url: nil,
- get_gateway_url: nil
-
if File.exists?("./config/dev.secret.exs") do
import_config "dev.secret.exs"
else
diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md
@@ -614,6 +614,19 @@ config :ex_aws, :s3,
host: "s3.eu-central-1.amazonaws.com"
```
+#### Pleroma.Uploaders.IPFS
+
+* `post_gateway_url`: URL with port of POST Gateway (unauthenticated)
+* `get_gateway_url`: URL of public GET Gateway
+
+Example:
+
+```elixir
+config :pleroma, Pleroma.Uploaders.IPFS,
+ post_gateway_url: "http://localhost:5001",
+ get_gateway_url: "http://<%= cid %>.ipfs.mydomain.com"
+```
+
### Upload filters
#### Pleroma.Upload.Filter.AnonymizeFilename
diff --git a/lib/pleroma/upload.ex b/lib/pleroma/upload.ex
@@ -235,10 +235,8 @@ defmodule Pleroma.Upload do
""
end
- uploader = Config.get([Pleroma.Upload, :uploader])
-
- if uploader == Pleroma.Uploaders.IPFS && String.contains?(base_url, "{CID}") do
- String.replace(base_url, "{CID}", path)
+ if String.contains?(base_url, "<%= cid %>") do
+ EEx.eval_string(base_url, cid: path)
else
[base_url, path]
|> Path.join()
diff --git a/lib/pleroma/uploaders/ipfs.ex b/lib/pleroma/uploaders/ipfs.ex
@@ -13,10 +13,10 @@ defmodule Pleroma.Uploaders.IPFS do
def get_file(file) do
b_url = Pleroma.Upload.base_url()
- if String.contains?(b_url, "{CID}") do
- {:ok, {:url, String.replace(b_url, "{CID}", URI.decode(file))}}
+ if String.contains?(b_url, "<%= cid %>") do
+ {:ok, {:url, EEx.eval_string(b_url, cid: URI.decode(file))}}
else
- {:error, "IPFS Get URL doesn't contain '{CID}' placeholder"}
+ {:error, "IPFS Get URL doesn't contain 'cid' placeholder"}
end
end
@@ -36,7 +36,11 @@ defmodule Pleroma.Uploaders.IPFS do
{:ok, ret} ->
case Jason.decode(ret.body) do
{:ok, ret} ->
- {:ok, {:file, ret["Hash"]}}
+ if Map.has_key?(ret, "Hash") do
+ {:ok, {:file, ret["Hash"]}}
+ else
+ {:error, "JSON doesn't contain Hash value"}
+ end
error ->
Logger.error("#{__MODULE__}: #{inspect(error)}")
@@ -45,7 +49,7 @@ defmodule Pleroma.Uploaders.IPFS do
error ->
Logger.error("#{__MODULE__}: #{inspect(error)}")
- {:error, "IPFS Gateway Upload failed"}
+ {:error, "IPFS Gateway upload failed"}
end
end
diff --git a/test/pleroma/uploaders/ipfs_test.exs b/test/pleroma/uploaders/ipfs_test.exs
@@ -0,0 +1,88 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Uploaders.IPFSTest do
+ use Pleroma.DataCase
+
+ alias Pleroma.Uploaders.IPFS
+ alias Tesla.Multipart
+
+ import Mock
+ import ExUnit.CaptureLog
+
+ setup do
+ clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.IPFS)
+ clear_config([Pleroma.Uploaders.IPFS])
+
+ clear_config(
+ [Pleroma.Uploaders.IPFS, :get_gateway_url],
+ "https://<%= cid %>.ipfs.mydomain.com"
+ )
+
+ clear_config([Pleroma.Uploaders.IPFS, :post_gateway_url], "http://localhost:5001")
+ end
+
+ describe "get_file/1" do
+ test "it returns path to ipfs file with cid as subdomain" do
+ assert IPFS.get_file("testcid") == {
+ :ok,
+ {:url, "https://testcid.ipfs.mydomain.com"}
+ }
+ end
+
+ test "it returns path to ipfs file with cid as path" do
+ clear_config(
+ [Pleroma.Uploaders.IPFS, :get_gateway_url],
+ "https://ipfs.mydomain.com/ipfs/<%= cid %>"
+ )
+
+ assert IPFS.get_file("testcid") == {
+ :ok,
+ {:url, "https://ipfs.mydomain.com/ipfs/testcid"}
+ }
+ end
+ end
+
+ describe "put_file/1" do
+ setup do
+ file_upload = %Pleroma.Upload{
+ name: "image-tet.jpg",
+ content_type: "image/jpeg",
+ path: "test_folder/image-tet.jpg",
+ tempfile: Path.absname("test/instance_static/add/shortcode.png")
+ }
+
+ [file_upload: file_upload]
+ end
+
+ test "save file", %{file_upload: file_upload} do
+ with_mock Pleroma.HTTP,
+ post: fn _, _, _, _ ->
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: "{\"Hash\":\"bafybeicrh7ltzx52yxcwrvxxckfmwhqdgsb6qym6dxqm2a4ymsakeshwoi\"}"
+ }}
+ end do
+ assert IPFS.put_file(file_upload) ==
+ {:ok, {:file, "bafybeicrh7ltzx52yxcwrvxxckfmwhqdgsb6qym6dxqm2a4ymsakeshwoi"}}
+ end
+ end
+
+ test "returns error", %{file_upload: file_upload} do
+ with_mock Pleroma.HTTP, post: fn _, _, _, _ -> {:error, "IPFS Gateway upload failed"} end do
+ assert capture_log(fn ->
+ assert IPFS.put_file(file_upload) == {:error, "IPFS Gateway upload failed"}
+ end) =~ "Elixir.Pleroma.Uploaders.IPFS: {:error, \"IPFS Gateway upload failed\"}"
+ end
+ end
+ end
+
+ describe "delete_file/1" do
+ test_with_mock "deletes file", Pleroma.HTTP,
+ post: fn _, _, _, _ -> {:ok, %{status_code: 204}} end do
+ assert :ok = IPFS.delete_file("image.jpg")
+ end
+ end
+end