feat(http): allow to provide self-signed certificates

Allow for the MOBILIZON_CA_CERT_PATH to be used to provide your own root certificates. The CAStore
and certify certificates stores should be always already be used as fallback instead of the system
store.

Closes #1355

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2024-02-09 12:13:22 +01:00
parent 9d99684402
commit baa11c18b0
No known key found for this signature in database
GPG Key ID: A061B9DDE0CA0773
9 changed files with 49 additions and 8 deletions

View File

@ -85,7 +85,9 @@ defmodule Mobilizon do
ErrorReporting.attach()
end
Supervisor.start_link(children, strategy: :one_for_one, name: Mobilizon.Supervisor)
with :ok <- load_certificates() do
Supervisor.start_link(children, strategy: :one_for_one, name: Mobilizon.Supervisor)
end
end
@spec config_change(keyword, keyword, [atom]) :: :ok
@ -160,4 +162,16 @@ defmodule Mobilizon do
end
defp setup_ecto_dev_logger(_), do: nil
defp load_certificates do
custom_cert_path = System.get_env("MOBILIZON_CA_CERT_PATH")
if is_binary(custom_cert_path) do
with :ok <- :tls_certificate_check.override_trusted_authorities({:file, custom_cert_path}) do
:public_key.cacerts_load(custom_cert_path)
end
else
:ok
end
end
end

View File

@ -3,7 +3,9 @@ defmodule Mobilizon.Service.HTTP.ActivityPub do
Tesla HTTP Client that is preconfigured to get and post ActivityPub content
"""
require Logger
alias Mobilizon.Config
import Mobilizon.Service.HTTP.Utils, only: [get_tls_config: 0]
@default_opts [
recv_timeout: 20_000
@ -13,7 +15,11 @@ defmodule Mobilizon.Service.HTTP.ActivityPub do
def client(options \\ []) do
headers = Keyword.get(options, :headers, [])
adapter = Application.get_env(:tesla, __MODULE__, [])[:adapter] || Tesla.Adapter.Hackney
opts = Keyword.merge(@default_opts, Keyword.get(options, :opts, []))
opts =
@default_opts
|> Keyword.merge(ssl_options: get_tls_config())
|> Keyword.merge(Keyword.get(options, :opts, []))
middleware = [
{Tesla.Middleware.Headers,

View File

@ -4,6 +4,7 @@ defmodule Mobilizon.Service.HTTP.GenericJSONClient do
"""
alias Mobilizon.Config
import Mobilizon.Service.HTTP.Utils, only: [get_tls_config: 0]
@default_opts [
recv_timeout: 20_000
@ -13,7 +14,11 @@ defmodule Mobilizon.Service.HTTP.GenericJSONClient do
def client(options \\ []) do
headers = Keyword.get(options, :headers, [])
adapter = Application.get_env(:tesla, __MODULE__, [])[:adapter] || Tesla.Adapter.Hackney
opts = Keyword.merge(@default_opts, Keyword.get(options, :opts, []))
opts =
@default_opts
|> Keyword.merge(ssl_options: get_tls_config())
|> Keyword.merge(Keyword.get(options, :opts, []))
middleware = [
{Tesla.Middleware.Headers,

View File

@ -6,12 +6,13 @@ defmodule Mobilizon.Service.HTTP.GeospatialClient do
use Tesla
alias Mobilizon.Config
import Mobilizon.Service.HTTP.Utils, only: [get_tls_config: 0]
@default_opts [
recv_timeout: 20_000
]
adapter(Tesla.Adapter.Hackney, @default_opts)
adapter(Tesla.Adapter.Hackney, Keyword.merge([ssl_options: get_tls_config()], @default_opts))
plug(Tesla.Middleware.FollowRedirects)

View File

@ -6,12 +6,13 @@ defmodule Mobilizon.Service.HTTP.HostMetaClient do
use Tesla
alias Mobilizon.Config
import Mobilizon.Service.HTTP.Utils, only: [get_tls_config: 0]
@default_opts [
recv_timeout: 20_000
]
adapter(Tesla.Adapter.Hackney, @default_opts)
adapter(Tesla.Adapter.Hackney, Keyword.merge([ssl_options: get_tls_config()], @default_opts))
plug(Tesla.Middleware.FollowRedirects)

View File

@ -5,12 +5,13 @@ defmodule Mobilizon.Service.HTTP.RemoteMediaDownloaderClient do
use Tesla
alias Mobilizon.Config
import Mobilizon.Service.HTTP.Utils, only: [get_tls_config: 0]
@default_opts [
recv_timeout: 20_000
]
adapter(Tesla.Adapter.Hackney, @default_opts)
adapter(Tesla.Adapter.Hackney, Keyword.merge([ssl_options: get_tls_config()], @default_opts))
plug(Tesla.Middleware.FollowRedirects)

View File

@ -5,12 +5,13 @@ defmodule Mobilizon.Service.HTTP.RichMediaPreviewClient do
use Tesla
alias Mobilizon.Config
import Mobilizon.Service.HTTP.Utils, only: [get_tls_config: 0]
@default_opts [
recv_timeout: 20_000
]
adapter(Tesla.Adapter.Hackney, @default_opts)
adapter(Tesla.Adapter.Hackney, Keyword.merge([ssl_options: get_tls_config()], @default_opts))
plug(Tesla.Middleware.FollowRedirects)

View File

@ -3,6 +3,17 @@ defmodule Mobilizon.Service.HTTP.Utils do
Utils for HTTP operations
"""
def get_tls_config do
cacertfile =
if is_nil(System.get_env("MOBILIZON_CA_CERT_PATH")) do
CAStore.file_path()
else
System.get_env("MOBILIZON_CA_CERT_PATH")
end
[cacertfile: cacertfile]
end
@spec get_header(Enum.t(), String.t()) :: String.t() | nil
def get_header(headers, key) do
key = String.downcase(key)

View File

@ -6,12 +6,13 @@ defmodule Mobilizon.Service.HTTP.WebfingerClient do
use Tesla
alias Mobilizon.Config
import Mobilizon.Service.HTTP.Utils, only: [get_tls_config: 0]
@default_opts [
recv_timeout: 20_000
]
adapter(Tesla.Adapter.Hackney, @default_opts)
adapter(Tesla.Adapter.Hackney, Keyword.merge([ssl_options: get_tls_config()], @default_opts))
plug(Tesla.Middleware.FollowRedirects)