defmodule Mobilizon.Web.ExportController do
  @moduledoc """
  Controller to serve exported files
  """
  use Mobilizon.Web, :controller
  plug(:put_layout, false)
  action_fallback(Mobilizon.Web.FallbackController)
  alias Mobilizon.Export
  import Mobilizon.Service.Export.Participants.Common, only: [enabled_formats: 0, export_path: 1]
  import Mobilizon.Web.Gettext, only: [dgettext: 3]

  # sobelow_skip ["Traversal.SendDownload"]
  @spec export(Plug.Conn.t(), map) :: {:error, :not_found} | Plug.Conn.t()
  def export(conn, %{"format" => format, "file" => file}) do
    if format in enabled_formats() do
      case Export.get_export(file, "event_participants", format) do
        %Export{file_name: file_name, file_path: file_path} ->
          local_path = Path.join(export_path(format), file_path)
          # We're using encode: false to disable escaping the filename with URI.encode_www_form/1
          # but it may introduce an security issue if the event title wasn't properly sanitized
          # https://github.com/phoenixframework/phoenix/pull/3344
          # https://owasp.org/www-community/attacks/HTTP_Response_Splitting
          send_download(conn, {:file, local_path}, filename: file_name, encode: false)

        nil ->
          {:error, :not_found}
      end
    else
      send_resp(
        conn,
        404,
        dgettext("errors", "Export to format %{format} is not enabled on this instance",
          format: format
        )
      )
    end
  end
end