Skip to content
Merged
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
49 changes: 32 additions & 17 deletions lib/hexdocs/plug.ex
Original file line number Diff line number Diff line change
Expand Up @@ -67,26 +67,41 @@ defmodule Hexdocs.Plug do
end

defp run(conn, _opts) do
case subdomain(conn.host) do
:error ->
send_resp(conn, 400, "")

{:ok, subdomain} ->
cond do
# OAuth callback - exchange code for tokens
conn.request_path == "/oauth/callback" ->
handle_oauth_callback(conn, subdomain)

# OAuth access token in session
access_token = get_session(conn, "access_token") ->
try_serve_page_oauth(conn, subdomain, access_token)

true ->
redirect_oauth(conn, subdomain)
end
if conn.host == Application.get_env(:hexdocs, :private_host) do
redirect_to_hexpm(conn)
else
case subdomain(conn.host) do
:error ->
send_resp(conn, 400, "")

{:ok, subdomain} ->
cond do
# OAuth callback - exchange code for tokens
conn.request_path == "/oauth/callback" ->
handle_oauth_callback(conn, subdomain)

# OAuth access token in session
access_token = get_session(conn, "access_token") ->
try_serve_page_oauth(conn, subdomain, access_token)

true ->
redirect_oauth(conn, subdomain)
end
end
end
end

defp redirect_to_hexpm(conn) do
url = Application.get_env(:hexdocs, :hexpm_url)
html = Plug.HTML.html_escape(url)
body = "<html><body>You are being <a href=\"#{html}\">redirected</a>.</body></html>"

conn
|> put_resp_header("location", url)
|> put_resp_header("content-type", "text/html")
|> send_resp(301, body)
end

defp redirect_oauth(conn, organization) do
code_verifier = Hexdocs.OAuth.generate_code_verifier()
code_challenge = Hexdocs.OAuth.generate_code_challenge(code_verifier)
Expand Down
15 changes: 13 additions & 2 deletions test/hexdocs/plug_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ defmodule Hexdocs.PlugTest do

@bucket :docs_private_bucket

test "requests without subdomain not supported" do
test "bare private host apex redirects to hexpm_url" do
# In the test env :host and :private_host are both "localhost", so a
# bare-host request hits the private-host-apex redirect.
conn = conn(:get, "http://localhost:5002/foo") |> call()
assert conn.status == 400
assert conn.status == 301
[location] = get_resp_header(conn, "location")
assert location == "http://localhost:5000"
end

describe "OAuth flow" do
Expand Down Expand Up @@ -340,6 +344,13 @@ defmodule Hexdocs.PlugTest do
conn = conn(:get, "http://phoenix.hexdocs.test:5002/index.html") |> call()
assert conn.status == 400
end

test "redirects bare private host apex to hexpm_url" do
conn = conn(:get, "http://hexorgs.test:5002/") |> call()
assert conn.status == 301
[location] = get_resp_header(conn, "location")
assert location == "http://localhost:5000"
end
end

test "sets security headers" do
Expand Down