Skip to content

Commit

Permalink
improve proxy gen
Browse files Browse the repository at this point in the history
  • Loading branch information
APB9785 committed Jan 15, 2025
1 parent ef0c4b2 commit 10ba70a
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 28 deletions.
78 changes: 56 additions & 22 deletions lib/mix/tasks/beacon.gen.proxy_endpoint.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,41 +26,42 @@ 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, """
Module #{inspect(proxy_endpoint_module_name)} already exists. Skipping.
""")

{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")
Expand Down Expand Up @@ -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
Expand Down
40 changes: 34 additions & 6 deletions test/mix/tasks/gen_proxy_endpoint.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

0 comments on commit 10ba70a

Please sign in to comment.