Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generalise SwaggerUI plug config supplementing for Phoenix app #547

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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_.
Expand Down
23 changes: 16 additions & 7 deletions lib/open_api_spex/plug/swagger_ui.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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
48 changes: 43 additions & 5 deletions test/plug/swagger_ui_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion test/server_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ defmodule OpenApiSpex.ServerTest do
]
)

Endpoint.start_link()
start_supervised!(Endpoint)
end
end