Provide sane defaults for SMTP
OTP’s default SSL/TLS settings are rather restricitive and in particular do not use system CA certs. In our case using system CA certs is virtually always desired and the lack of it leads to non-obvious errors. Manually configuring system CA certs from in-database config also isn’t straightforward. Furthermore, gen_smtp uses a different set of connection options for direct SSL/TLS and a later TLS upgrade providing additional confusion and complexity in how to configure this. Thus provide some suitable defaults for sending SMTP emails. Everything can still be overriden by admins if necessary. Note: defaults are not appended when validating the config in hopes of improving the error message (as the required relay key is already accessed to generate defaults for optional fields) Fixes: #660
This commit is contained in:
parent
e97d08ee98
commit
192480093c
1 changed files with 52 additions and 3 deletions
|
@ -55,12 +55,61 @@ def deliver!(email, config) do
|
||||||
|
|
||||||
@doc false
|
@doc false
|
||||||
def validate_dependency do
|
def validate_dependency do
|
||||||
parse_config([])
|
parse_config([], defaults: false)
|
||||||
|> Keyword.get(:adapter)
|
|> Keyword.get(:adapter)
|
||||||
|> Swoosh.Mailer.validate_dependency()
|
|> Swoosh.Mailer.validate_dependency()
|
||||||
end
|
end
|
||||||
|
|
||||||
defp parse_config(config) do
|
defp ensure_charlist(input) do
|
||||||
Swoosh.Mailer.parse_config(@otp_app, __MODULE__, @mailer_config, config)
|
case input do
|
||||||
|
i when is_binary(i) -> String.to_charlist(input)
|
||||||
|
i when is_list(i) -> i
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp default_config(adapter, conf, opts)
|
||||||
|
|
||||||
|
defp default_config(_, _, defaults: false) do
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
|
||||||
|
defp default_config(Swoosh.Adapters.SMTP, conf, _) do
|
||||||
|
# gen_smtp and Erlang's tls defaults are very barebones, if nothing is set.
|
||||||
|
# Add sane defaults for our usecase to make config less painful for admins
|
||||||
|
relay = ensure_charlist(Keyword.get(conf, :relay))
|
||||||
|
ssl_disabled = Keyword.get(conf, :ssl) === false
|
||||||
|
os_cacerts = :public_key.cacerts_get()
|
||||||
|
|
||||||
|
common_tls_opts = [
|
||||||
|
cacerts: os_cacerts,
|
||||||
|
versions: [:"tlsv1.2", :"tlsv1.3"],
|
||||||
|
verify: :verify_peer,
|
||||||
|
# some versions have supposedly issues verifying wildcard certs without this
|
||||||
|
server_name_indication: relay,
|
||||||
|
# the default of 10 is too restrictive
|
||||||
|
depth: 32
|
||||||
|
]
|
||||||
|
|
||||||
|
[
|
||||||
|
auth: :always,
|
||||||
|
no_mx_lookups: false,
|
||||||
|
# Direct SSL/TLS
|
||||||
|
# (if ssl was explicitly disabled, we must not pass TLS options to the socket)
|
||||||
|
ssl: true,
|
||||||
|
sockopts: if(ssl_disabled, do: [], else: common_tls_opts),
|
||||||
|
# STARTTLS upgrade (can't be set to :always when already using direct TLS)
|
||||||
|
tls: :if_available,
|
||||||
|
tls_options: common_tls_opts
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
defp default_config(_, _, _), do: []
|
||||||
|
|
||||||
|
defp parse_config(config, opts \\ []) do
|
||||||
|
conf = Swoosh.Mailer.parse_config(@otp_app, __MODULE__, @mailer_config, config)
|
||||||
|
adapter = Keyword.get(conf, :adapter)
|
||||||
|
|
||||||
|
default_config(adapter, conf, opts)
|
||||||
|
|> Keyword.merge(conf)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue