Make FrontEndAnalytics provide CSP configuration

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2022-04-06 16:53:20 +02:00
parent da2254089c
commit e3adc0684f
No known key found for this signature in database
GPG key ID: A061B9DDE0CA0773
6 changed files with 59 additions and 9 deletions

View file

@ -13,7 +13,12 @@ defmodule Mobilizon.Service.FrontEndAnalytics do
@doc """
The configuration for the service
"""
@callback configuration() :: map()
@callback configuration() :: keyword()
@doc """
The CSP configuration to add for the service to work
"""
@callback csp() :: keyword()
@spec providers :: list(module())
def providers do
@ -27,7 +32,14 @@ defmodule Mobilizon.Service.FrontEndAnalytics do
Enum.reduce(providers(), [], &load_config/2)
end
@spec load_config(module(), map()) :: map()
@spec csp :: keyword()
def csp do
providers()
|> Enum.map(& &1.csp())
|> Enum.reduce([], &merge_csp_config/2)
end
@spec load_config(module(), list(map())) :: list(map())
defp load_config(provider, acc) do
acc ++
[
@ -50,4 +62,10 @@ defmodule Mobilizon.Service.FrontEndAnalytics do
defp type(val) when is_float(val), do: :float
defp type(val) when is_boolean(val), do: :boolean
defp type(val) when is_binary(val), do: :string
defp merge_csp_config(config, global_config) do
Keyword.merge(global_config, config, fn _key, global, config ->
"#{global} #{config}"
end)
end
end

View file

@ -25,6 +25,16 @@ defmodule Mobilizon.Service.FrontEndAnalytics.Matomo do
def configuration do
:mobilizon
|> Application.get_env(__MODULE__, [])
|> Keyword.drop([:enabled])
|> Keyword.drop([:enabled, :csp])
end
@doc """
The CSP configuration to add for the service to work
"""
@impl FrontEndAnalytics
def csp do
:mobilizon
|> Application.get_env(__MODULE__, [])
|> Keyword.get(:csp, [])
end
end

View file

@ -26,6 +26,16 @@ defmodule Mobilizon.Service.FrontEndAnalytics.Plausible do
def configuration do
:mobilizon
|> Application.get_env(__MODULE__, [])
|> Keyword.drop([:enabled])
|> Keyword.drop([:enabled, :csp])
end
@doc """
The CSP configuration to add for the service to work
"""
@impl FrontEndAnalytics
def csp do
:mobilizon
|> Application.get_env(__MODULE__, [])
|> Keyword.get(:csp, [])
end
end

View file

@ -26,6 +26,16 @@ defmodule Mobilizon.Service.FrontEndAnalytics.Sentry do
def configuration do
:mobilizon
|> Application.get_env(__MODULE__, [])
|> Keyword.drop([:enabled])
|> Keyword.drop([:enabled, :csp])
end
@doc """
The CSP configuration to add for the service to work
"""
@impl FrontEndAnalytics
def csp do
:mobilizon
|> Application.get_env(__MODULE__, [])
|> Keyword.get(:csp, [])
end
end

View file

@ -9,6 +9,7 @@ defmodule Mobilizon.Web.Plugs.HTTPSecurityPlug do
"""
alias Mobilizon.Config
alias Mobilizon.Service.FrontEndAnalytics
import Plug.Conn
require Logger
@ -136,8 +137,9 @@ defmodule Mobilizon.Web.Plugs.HTTPSecurityPlug do
@spec get_csp_config(atom(), Keyword.t()) :: iodata()
defp get_csp_config(type, options) do
options
|> Keyword.get(type, Config.get([:http_security, :csp_policy, type]))
|> Enum.join(" ")
config_policy = Keyword.get(options, type, Config.get([:http_security, :csp_policy, type]))
front_end_analytics_policy = [Keyword.get(FrontEndAnalytics.csp(), type, [])]
Enum.join(config_policy ++ front_end_analytics_policy, " ")
end
end

View file

@ -73,7 +73,7 @@ defmodule Mobilizon.Web.Plugs.HTTPSecurityPlugTest do
[csp] = Conn.get_resp_header(conn, "content-security-policy")
assert csp =~
~r/script-src 'self' 'unsafe-eval' 'sha256-[\w+\/=]*' example.com matomo.example.com;/
~r/script-src 'self' 'unsafe-eval' 'sha256-[\w+\/=]*' example.com matomo.example.com ;/
end
end