From 10ba70a15148e332175dbc9db9bca2e055dcdf98 Mon Sep 17 00:00:00 2001 From: APB9785 <74077809+APB9785@users.noreply.github.com> Date: Tue, 14 Jan 2025 19:42:29 -0600 Subject: [PATCH] improve proxy gen --- lib/mix/tasks/beacon.gen.proxy_endpoint.ex | 78 ++++++++++++++++------ test/mix/tasks/gen_proxy_endpoint.exs | 40 +++++++++-- 2 files changed, 90 insertions(+), 28 deletions(-) diff --git a/lib/mix/tasks/beacon.gen.proxy_endpoint.ex b/lib/mix/tasks/beacon.gen.proxy_endpoint.ex index 2921b41f..31225414 100644 --- a/lib/mix/tasks/beacon.gen.proxy_endpoint.ex +++ b/lib/mix/tasks/beacon.gen.proxy_endpoint.ex @@ -26,25 +26,8 @@ defmodule Mix.Tasks.Beacon.Gen.ProxyEndpoint do @doc false def igniter(igniter) do - otp_app = Igniter.Project.Application.app_name(igniter) - {igniter, router} = Beacon.Igniter.select_router!(igniter) - {igniter, fallback_endpoint} = Beacon.Igniter.select_endpoint(igniter, router, "Select a fallback endpoint (default app Endpoint):") proxy_endpoint_module_name = Igniter.Libs.Phoenix.web_module_name(igniter, "ProxyEndpoint") - signing_salt = Keyword.get_lazy(igniter.args.argv, :signing_salt, fn -> random_string(8) end) - igniter - |> create_proxy_endpoint_module(otp_app, fallback_endpoint, proxy_endpoint_module_name) - |> add_session_options_config(otp_app, signing_salt, igniter.args.options) - |> add_proxy_endpoint_config(otp_app, proxy_endpoint_module_name, signing_salt) - |> update_fallback_endpoint_signing_salt(otp_app, fallback_endpoint, signing_salt) - |> Igniter.add_notice(""" - ProxyEndpoint generated successfully. - - This enables your application to serve sites at multiple hosts, each with their own Endpoint. - """) - end - - defp create_proxy_endpoint_module(igniter, otp_app, fallback_endpoint, proxy_endpoint_module_name) do case Igniter.Project.Module.module_exists(igniter, proxy_endpoint_module_name) do {true, igniter} -> Igniter.add_notice(igniter, """ @@ -52,15 +35,33 @@ defmodule Mix.Tasks.Beacon.Gen.ProxyEndpoint do """) {false, igniter} -> - Igniter.Project.Module.create_module(igniter, proxy_endpoint_module_name, """ - use Beacon.ProxyEndpoint, - otp_app: #{inspect(otp_app)}, - session_options: Application.compile_env!(#{inspect(otp_app)}, :session_options), - fallback: #{inspect(fallback_endpoint)} + otp_app = Igniter.Project.Application.app_name(igniter) + {igniter, router} = Beacon.Igniter.select_router!(igniter) + {igniter, fallback_endpoint} = Beacon.Igniter.select_endpoint(igniter, router, "Select a fallback endpoint (default app Endpoint):") + signing_salt = Keyword.get_lazy(igniter.args.argv, :signing_salt, fn -> random_string(8) end) + + igniter + |> create_proxy_endpoint_module(otp_app, fallback_endpoint, proxy_endpoint_module_name) + |> add_session_options_config(otp_app, signing_salt, igniter.args.options) + |> add_proxy_endpoint_config(otp_app, proxy_endpoint_module_name, signing_salt) + |> update_fallback_endpoint_signing_salt(otp_app, fallback_endpoint, signing_salt) + |> Igniter.add_notice(""" + ProxyEndpoint generated successfully. + + This enables your application to serve sites at multiple hosts, each with their own Endpoint. """) end end + defp create_proxy_endpoint_module(igniter, otp_app, fallback_endpoint, proxy_endpoint_module_name) do + Igniter.Project.Module.create_module(igniter, proxy_endpoint_module_name, """ + use Beacon.ProxyEndpoint, + otp_app: #{inspect(otp_app)}, + session_options: Application.compile_env!(#{inspect(otp_app)}, :session_options), + fallback: #{inspect(fallback_endpoint)} + """) + end + def add_session_options_config(igniter, otp_app, signing_salt, options) do key = Keyword.get_lazy(options, :key, fn -> "_#{otp_app}_key" end) same_site = Keyword.get(options, :same_site, "Lax") @@ -102,6 +103,39 @@ defmodule Mix.Tasks.Beacon.Gen.ProxyEndpoint do [proxy_endpoint_module_name, :check_origin], {:code, Sourceror.parse_string!("[]")} ) + |> Igniter.Project.Config.configure( + "runtime.exs", + otp_app, + [proxy_endpoint_module_name, :url], + {:code, Sourceror.parse_string!("[port: 443, scheme: \"https\"]")} + ) + |> Igniter.Project.Config.configure( + "runtime.exs", + otp_app, + [proxy_endpoint_module_name, :http], + {:code, Sourceror.parse_string!("[ip: {0, 0, 0, 0, 0, 0, 0, 0}, port: port]")} + ) + |> Igniter.Project.Config.configure( + "runtime.exs", + otp_app, + [proxy_endpoint_module_name, :secret_key_base], + {:code, Sourceror.parse_string!("secret_key_base")} + ) + |> Igniter.Project.Config.configure( + "dev.exs", + otp_app, + [proxy_endpoint_module_name, :http], + {:code, Sourceror.parse_string!("[ip: {127, 0, 0, 1}, port: 4000]")} + ) + |> Igniter.Project.Config.configure("dev.exs", otp_app, [proxy_endpoint_module_name, :check_origin], {:code, Sourceror.parse_string!("false")}) + |> Igniter.Project.Config.configure("dev.exs", otp_app, [proxy_endpoint_module_name, :debug_errors], {:code, Sourceror.parse_string!("true")}) + # TODO: ensure secret key valid + |> Igniter.Project.Config.configure( + "dev.exs", + otp_app, + [proxy_endpoint_module_name, :secret_key_base], + "A0DSgxjGCYZ6fCIrBlg6L+qC/cdoFq5Rmomm53yacVmN95Wcpl57Gv0sTJjKjtIp" + ) end defp update_fallback_endpoint_signing_salt(igniter, otp_app, fallback_endpoint, signing_salt) do diff --git a/test/mix/tasks/gen_proxy_endpoint.exs b/test/mix/tasks/gen_proxy_endpoint.exs index bdffc01a..e4884da6 100644 --- a/test/mix/tasks/gen_proxy_endpoint.exs +++ b/test/mix/tasks/gen_proxy_endpoint.exs @@ -20,13 +20,15 @@ defmodule Mix.Tasks.Beacon.GenProxyEndpointTest do |> Igniter.compose_task("beacon.gen.proxy_endpoint") |> assert_creates("lib/test_web/proxy_endpoint.ex", """ defmodule TestWeb.ProxyEndpoint do - @session_options Application.compile_env!(:test, :session_options) - use Beacon.ProxyEndpoint, otp_app: :test, session_options: @session_options, fallback: TestWeb.Endpoint + use Beacon.ProxyEndpoint, + otp_app: :test, + session_options: Application.compile_env!(:test, :session_options), + fallback: TestWeb.Endpoint end """) end - test "update config", %{project: project} do + test "update config.exs", %{project: project} do project |> Igniter.compose_task("beacon.gen.proxy_endpoint", signing_salt: "SNUXnTNM") # add session options config @@ -44,12 +46,38 @@ defmodule Mix.Tasks.Beacon.GenProxyEndpointTest do """) # add proxy endpoint config |> assert_has_patch("config/config.exs", """ - 10 + |config :test, TestWeb.ProxyEndpoint, adapter: Bandit.PhoenixAdapter, live_view: [signing_salt: "SNUXnTNM"] - 11 + | + 10 + |config :test, TestWeb.ProxyEndpoint, adapter: Bandit.PhoenixAdapter, live_view: [signing_salt: "SNUXnTNM"] + 11 + | """) # update fallback endpoint signing salt |> assert_has_patch("config/config.exs", """ - 31 + | live_view: [signing_salt: "SNUXnTNM"] + 31 + | live_view: [signing_salt: "SNUXnTNM"] + """) + end + + test "update dev.exs", %{project: project} do + project + |> Igniter.compose_task("beacon.gen.proxy_endpoint", signing_salt: "SNUXnTNM") + |> assert_has_patch("config/dev.exs", """ + 3 + |config :test, TestWeb.ProxyEndpoint, + 4 + | http: [ip: {127, 0, 0, 1}, port: 4000], + 5 + | check_origin: false, + 6 + | debug_errors: true, + 7 + | secret_key_base: "A0DSgxjGCYZ6fCIrBlg6L+qC/cdoFq5Rmomm53yacVmN95Wcpl57Gv0sTJjKjtIp" + 8 + | + """) + end + + test "update runtime.exs", %{project: project} do + project + |> Igniter.compose_task("beacon.gen.proxy_endpoint", signing_salt: "SNUXnTNM") + |> assert_has_patch("config/runtime.exs", """ + 3 + |config :test, TestWeb.ProxyEndpoint, + 4 + | check_origin: [], + 5 + | url: [port: 443, scheme: "https"], + 6 + | http: [ip: {0, 0, 0, 0, 0, 0, 0, 0}, port: port], + 7 + | secret_key_base: secret_key_base + 8 + | """) end end