diff --git a/README.md b/README.md index 2bcede5b..57d506b9 100644 --- a/README.md +++ b/README.md @@ -338,6 +338,8 @@ scope "/api" do end ``` +Additionally, you can set plug option values as a tuple. In this tuple, the first element should be either `:endpoint_url` or `:endpoint_path` and the second element should be the specific path. This tuple will be converted to the respective URL or path of the Endpoint. This feature is particularly useful in cases where your Phoenix app's Endpoint URL is configured with a non-empty path. It allows you to obtain the full path to the local spec or, as an example, to retrieve the URL for the `oauth2RedirectUrl` parameter, which can then be passed to the [Swagger UI configuration](https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/). + ## Importing an existing schema file > :warning: This functionality currently converts Strings into Atoms, which makes it potentially [vulnerable to DoS attacks](https://til.hashrocket.com/posts/gkwwfy9xvw-converting-strings-to-atoms-safely). We recommend that you load Open API Schemas from _known files_ during application startup and _not dynamically from external sources at runtime_. diff --git a/lib/open_api_spex/plug/swagger_ui.ex b/lib/open_api_spex/plug/swagger_ui.ex index 6c3ddd6c..b68b0239 100644 --- a/lib/open_api_spex/plug/swagger_ui.ex +++ b/lib/open_api_spex/plug/swagger_ui.ex @@ -193,14 +193,23 @@ defmodule OpenApiSpex.Plug.SwaggerUI do end if Code.ensure_loaded?(Phoenix.Controller) do - defp supplement_config(%{oauth2_redirect_url: {:endpoint_url, path}} = config, conn) do + defp supplement_config(config, conn) do endpoint_module = Phoenix.Controller.endpoint_module(conn) - url = Path.join(endpoint_module.url(), path) - Map.put(config, :oauth2_redirect_url, url) - end - end - defp supplement_config(config, _conn) do - config + Map.new(config, fn + {k, {:endpoint_url, path}} -> + {k, Path.join(endpoint_module.url(), endpoint_module.path(path))} + + {k, {:endpoint_path, path}} -> + {k, endpoint_module.path(path)} + + k_v -> + k_v + end) + end + else + defp supplement_config(config, _conn) do + config + end end end diff --git a/test/plug/swagger_ui_test.exs b/test/plug/swagger_ui_test.exs index e53b21d6..7aa766ea 100644 --- a/test/plug/swagger_ui_test.exs +++ b/test/plug/swagger_ui_test.exs @@ -2,15 +2,53 @@ defmodule OpenApiSpec.Plug.SwaggerUITest do use ExUnit.Case alias OpenApiSpex.Plug.SwaggerUI - - @opts SwaggerUI.init(path: "/ui") + alias OpenApiSpexTest.Endpoint test "renders csrf token" do + start_supervised!(Endpoint) + + config = SwaggerUI.init(path: "/ui") + token = Plug.CSRFProtection.get_csrf_token() - conn = Plug.Test.conn(:get, "/ui") - conn = SwaggerUI.call(conn, @opts) - assert conn.resp_body =~ ~r[pathname.+?/ui] + conn = + Plug.Test.conn(:get, "/ui") + |> Plug.Conn.put_private(:phoenix_endpoint, Endpoint) + + conn = SwaggerUI.call(conn, config) + assert conn.resp_body =~ ~r[pathname.+?"/ui"] assert String.contains?(conn.resp_body, token) end + + test "generate actual path dependent to endpoint" do + Application.put_env(:open_api_spex_test, Endpoint, url: [path: "/some-prefix"]) + + start_supervised!(Endpoint) + + config = SwaggerUI.init(path: {:endpoint_path, "/ui"}) + + conn = + Plug.Test.conn(:get, "/ui") + |> Plug.Conn.put_private(:phoenix_endpoint, Endpoint) + + conn = SwaggerUI.call(conn, config) + assert conn.resp_body =~ ~r[pathname.+?"/some-prefix/ui"] + end + + test "generate actual url dependent to endpoint" do + Application.put_env(:open_api_spex_test, Endpoint, + url: [scheme: "https", host: "some-host.com", port: 1234, path: "/some-prefix"] + ) + + start_supervised!(Endpoint) + + config = SwaggerUI.init(path: {:endpoint_url, "/ui"}) + + conn = + Plug.Test.conn(:get, "/ui") + |> Plug.Conn.put_private(:phoenix_endpoint, Endpoint) + + conn = SwaggerUI.call(conn, config) + assert conn.resp_body =~ ~r[pathname.+?"https://some-host.com:1234/some-prefix/ui"] + end end diff --git a/test/server_test.exs b/test/server_test.exs index 0a984f0f..f026be43 100644 --- a/test/server_test.exs +++ b/test/server_test.exs @@ -27,6 +27,6 @@ defmodule OpenApiSpex.ServerTest do ] ) - Endpoint.start_link() + start_supervised!(Endpoint) end end