diff --git a/core/priv/gettext/en/LC_MESSAGES/eyra-storage.po b/core/priv/gettext/en/LC_MESSAGES/eyra-storage.po
index a506ecdec..47b10a265 100644
--- a/core/priv/gettext/en/LC_MESSAGES/eyra-storage.po
+++ b/core/priv/gettext/en/LC_MESSAGES/eyra-storage.po
@@ -75,6 +75,10 @@ msgstr "WebDAV Url"
msgid "surfresearchdrive.folder.label"
msgstr "Folder name"
+#, elixir-autogen, elixir-format
+msgid "surfresearchdrive.passphrase.label"
+msgstr "Passphrase for encryption"
+
#, elixir-autogen, elixir-format
msgid "aws.annotation"
msgstr "
"
diff --git a/core/priv/gettext/eyra-storage.pot b/core/priv/gettext/eyra-storage.pot
index afa3f495b..2151bb1ac 100644
--- a/core/priv/gettext/eyra-storage.pot
+++ b/core/priv/gettext/eyra-storage.pot
@@ -75,6 +75,10 @@ msgstr ""
msgid "surfresearchdrive.folder.label"
msgstr ""
+#, elixir-autogen, elixir-format
+msgid "surfresearchdrive.passphrase.label"
+msgstr ""
+
#, elixir-autogen, elixir-format
msgid "aws.annotation"
msgstr ""
diff --git a/core/priv/repo/migrations/20231025125051_add_storage.exs b/core/priv/repo/migrations/20231025125051_add_storage.exs
index e2a6f573f..06ba19dc9 100644
--- a/core/priv/repo/migrations/20231025125051_add_storage.exs
+++ b/core/priv/repo/migrations/20231025125051_add_storage.exs
@@ -38,6 +38,7 @@ defmodule Core.Repo.Migrations.AddStorage do
add(:password, :string)
add(:url, :string)
add(:folder, :string)
+ add(:passphrase, :string)
timestamps()
end
diff --git a/core/systems/storage/surfresearchdrive/backend.ex b/core/systems/storage/surfresearchdrive/backend.ex
index 407a313cb..eb4a56e7a 100644
--- a/core/systems/storage/surfresearchdrive/backend.ex
+++ b/core/systems/storage/surfresearchdrive/backend.ex
@@ -1,7 +1,7 @@
defmodule Systems.Storage.SurfResearchDrive.Backend do
@behaviour Systems.Storage.Backend
- alias Systems.Storage.SurfResearchDrive
+ alias Systems.Storage.SurfResearchDrive.Encryption
require Logger
@@ -10,7 +10,8 @@ defmodule Systems.Storage.SurfResearchDrive.Backend do
"user" => username,
"password" => password,
"url" => url,
- "folder" => folder
+ "folder" => folder,
+ "passphrase" => passphrase,
} = _endpoint,
data,
meta_data
@@ -24,6 +25,13 @@ defmodule Systems.Storage.SurfResearchDrive.Backend do
{"Authorization", "Basic #{credentials}"}
]
+
+ data = if passphrase != nil do
+ Encryption.encrypt(data, passphrase)
+ else
+ data
+ end
+
case HTTPoison.put(file_url, data, headers) do
{:ok, %{status_code: 201}} ->
:ok
@@ -32,7 +40,7 @@ defmodule Systems.Storage.SurfResearchDrive.Backend do
{:error, "status_code=#{status_code},message=#{body}"}
{:error, error} ->
- Logger.error("[SurfResearchDrive.Backend] #{error}")
+ IO.inspect(error)
{:error, error}
end
end
diff --git a/core/systems/storage/surfresearchdrive/encryption.ex b/core/systems/storage/surfresearchdrive/encryption.ex
new file mode 100644
index 000000000..f2cda456c
--- /dev/null
+++ b/core/systems/storage/surfresearchdrive/encryption.ex
@@ -0,0 +1,42 @@
+defmodule Systems.Storage.SurfResearchDrive.Encryption do
+ @moduledoc """
+ Documentation for `Systems.Storage.SurfResearchDrive.Encryption`.
+ """
+
+ @doc """
+ Encrypt file with AES-256-CBC
+
+ The hashed passphrase is the encryption key
+ The hash function is there to guarantee the key consists of 256 bits
+ The hasing function does not offer protection.
+ If you know the hash or the passphrase you can decrypt the data
+
+ Decryption can be done with:
+ openssl enc -d -aes-256-cbc -in <(tail -c +17 file.enc) \
+ -out file.txt \
+ -K \
+ -iv
+ """
+ def encrypt(content, passphrase) do
+
+ # generate key and iv
+ key = :crypto.hash(:sha256, passphrase)
+ iv = :crypto.strong_rand_bytes(16)
+
+ padded_content = pad(content, 16)
+
+ # Encrypt content
+ cipher_text = :crypto.crypto_one_time(:aes_256_cbc, key, iv, padded_content, true)
+
+ # Prepend IV and write the result
+ iv <> cipher_text
+ end
+
+ @doc """
+ Applies PKCS7 padding to the given binary.
+ """
+ def pad(data, block_size) do
+ padding_size = block_size - rem(byte_size(data), block_size)
+ data <> :binary.copy(<>, padding_size)
+ end
+end
diff --git a/core/systems/storage/surfresearchdrive/endpoint_form.ex b/core/systems/storage/surfresearchdrive/endpoint_form.ex
index 0aaf8a02d..d3b960935 100644
--- a/core/systems/storage/surfresearchdrive/endpoint_form.ex
+++ b/core/systems/storage/surfresearchdrive/endpoint_form.ex
@@ -13,11 +13,9 @@ defmodule Systems.Storage.SurfResearchDrive.EndpointForm do
<.password_input form={form} field={:password} label_text={dgettext("eyra-storage", "surfresearchdrive.password.label")} debounce="0" reserve_error_space={false} />
<.text_input form={form} field={:url} label_text={dgettext("eyra-storage", "surfresearchdrive.url.label")} placeholder="https://{url}/remote.php/webdav/>" debounce="0" reserve_error_space={false} />
<.text_input form={form} field={:folder} label_text={dgettext("eyra-storage", "surfresearchdrive.folder.label")} debounce="0" reserve_error_space={false} />
+ <.text_input form={form} field={:passphrase} label_text={dgettext("eyra-storage", "surfresearchdrive.passphrase.label")} placeholder="Leave blank for no encryption" debounce="0" reserve_error_space={false} />
- <%= if @show_status do %>
- <.account_status connected?={@connected?}/>
- <% end %>
diff --git a/core/systems/storage/surfresearchdrive/endpoint_model.ex b/core/systems/storage/surfresearchdrive/endpoint_model.ex
index ae5d68a4d..05fdd8c6d 100644
--- a/core/systems/storage/surfresearchdrive/endpoint_model.ex
+++ b/core/systems/storage/surfresearchdrive/endpoint_model.ex
@@ -5,16 +5,17 @@ defmodule Systems.Storage.SurfResearchDrive.EndpointModel do
import Ecto.Changeset
alias Systems.Storage.SurfResearchDrive
- @fields ~w(user password url folder)a
+ @fields ~w(user password url folder passphrase)a
@required_fields @fields
@derive {Jason.Encoder, only: @fields}
- @derive {Inspect, except: [:user, :password]}
+ @derive {Inspect, except: [:user, :password, :passphrase]}
schema "storage_endpoints_surfresearchdrive" do
field(:user, :string)
field(:password, :string)
field(:url, :string)
field(:folder, :string)
+ field(:passphrase, :string)
timestamps()
end