mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-09-04 20:14:57 +08:00
Handle token auth under the same /authenticate route as password (#1104)
* auth token mode routes /authentication * Update lib/livebook_web/controllers/auth_controller.ex Co-authored-by: Jonatan Kłosko <jonatanklosko@gmail.com>
This commit is contained in:
parent
d031d2b7a3
commit
5606326203
5 changed files with 40 additions and 64 deletions
|
@ -1,12 +1,14 @@
|
|||
defmodule LivebookWeb.AuthController do
|
||||
use LivebookWeb, :controller
|
||||
|
||||
plug :require_unauthenticated_password
|
||||
plug :require_unauthenticated
|
||||
|
||||
alias LivebookWeb.AuthPlug
|
||||
|
||||
defp require_unauthenticated_password(conn, _opts) do
|
||||
if Livebook.Config.auth_mode() != :password or AuthPlug.authenticated?(conn, :password) do
|
||||
defp require_unauthenticated(conn, _opts) do
|
||||
auth_mode = Livebook.Config.auth_mode()
|
||||
|
||||
if auth_mode not in [:password, :token] or AuthPlug.authenticated?(conn, auth_mode) do
|
||||
redirect_home(conn)
|
||||
else
|
||||
conn
|
||||
|
@ -14,7 +16,7 @@ defmodule LivebookWeb.AuthController do
|
|||
end
|
||||
|
||||
def index(conn, _params) do
|
||||
render(conn, "index.html")
|
||||
render(conn, "index.html", auth_mode: Livebook.Config.auth_mode())
|
||||
end
|
||||
|
||||
def authenticate(conn, %{"password" => password}) do
|
||||
|
@ -27,6 +29,16 @@ defmodule LivebookWeb.AuthController do
|
|||
end
|
||||
end
|
||||
|
||||
def authenticate(conn, %{"token" => token}) do
|
||||
conn = AuthPlug.store(conn, :token, token)
|
||||
|
||||
if AuthPlug.authenticated?(conn, :token) do
|
||||
redirect_home(conn)
|
||||
else
|
||||
index(conn, %{})
|
||||
end
|
||||
end
|
||||
|
||||
defp redirect_home(conn) do
|
||||
conn
|
||||
|> redirect(to: "/")
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
defmodule LivebookWeb.InvalidTokenError do
|
||||
defexception plug_status: 401, message: "invalid token"
|
||||
end
|
||||
|
||||
defmodule LivebookWeb.AuthPlug do
|
||||
@moduledoc false
|
||||
|
||||
|
@ -55,9 +51,7 @@ defmodule LivebookWeb.AuthPlug do
|
|||
end
|
||||
|
||||
defp authenticate(conn, :password) do
|
||||
conn
|
||||
|> redirect(to: "/authenticate")
|
||||
|> halt()
|
||||
redirect_to_authenticate(conn)
|
||||
end
|
||||
|
||||
defp authenticate(conn, :token) do
|
||||
|
@ -70,10 +64,16 @@ defmodule LivebookWeb.AuthPlug do
|
|||
|> redirect(to: path_with_query(conn.request_path, query_params))
|
||||
|> halt()
|
||||
else
|
||||
raise LivebookWeb.InvalidTokenError
|
||||
redirect_to_authenticate(conn)
|
||||
end
|
||||
end
|
||||
|
||||
defp redirect_to_authenticate(conn) do
|
||||
conn
|
||||
|> redirect(to: "/authenticate")
|
||||
|> halt()
|
||||
end
|
||||
|
||||
defp path_with_query(path, params) when params == %{}, do: path
|
||||
defp path_with_query(path, params), do: path <> "?" <> URI.encode_query(params)
|
||||
|
||||
|
|
|
@ -8,12 +8,21 @@
|
|||
</div>
|
||||
|
||||
<div class="max-w-2xl text-center text-gray-300">
|
||||
<%= if @auth_mode == :password do %>
|
||||
Type password to access the Livebook.
|
||||
<% else %>
|
||||
Please check out the console for authentication URL
|
||||
or type the token directly here.
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="text-2xl text-gray-50 w-full pt-2">
|
||||
<form method="post" class="flex flex-col space-y-4 items-center">
|
||||
<input type="hidden" value="<%= Phoenix.Controller.get_csrf_token() %>" name="_csrf_token"/>
|
||||
<input type="password" name="password" class="input" placeholder="Password" autofocus />
|
||||
<%= if @auth_mode == :password do %>
|
||||
<input type="password" name="password" class="input" placeholder="Password" autofocus />
|
||||
<% else %>
|
||||
<input type="text" name="token" class="input" placeholder="Token" autofocus />
|
||||
<% end %>
|
||||
<button type="submit" class="button-base button-blue">
|
||||
Authenticate
|
||||
</button>
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<title><%= @status %> - Livebook</title>
|
||||
<link rel="stylesheet" href="<%= Routes.static_path(@conn, "/css/app.css") %>"/>
|
||||
</head>
|
||||
<body>
|
||||
<div class="h-screen flex items-center justify-center bg-gray-900">
|
||||
<div class="flex flex-col space-y-4 items-center">
|
||||
<a href="/">
|
||||
<img src="/images/logo.png" height="128" width="128" alt="livebook" />
|
||||
</a>
|
||||
<div class="text-2xl text-gray-50">
|
||||
Authentication required
|
||||
</div>
|
||||
|
||||
<div class="max-w-2xl text-center text-gray-300">
|
||||
Please check out the console for authentication URL
|
||||
or type the token directly here.
|
||||
</div>
|
||||
|
||||
<div class="text-2xl text-gray-50 w-full pt-2">
|
||||
<form method="get" class="flex flex-col space-y-4 items-center">
|
||||
<input type="text" name="token" class="input" placeholder="Token" autofocus />
|
||||
<button type="submit" class="button-base button-blue">
|
||||
Authenticate
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -31,13 +31,9 @@ defmodule LivebookWeb.AuthPlugTest do
|
|||
end
|
||||
|
||||
@tag token: "grumpycat"
|
||||
test "returns authentication error when token is set and none provided", %{conn: conn} do
|
||||
{_, _, resp_body} =
|
||||
assert_error_sent 401, fn ->
|
||||
get(conn, "/")
|
||||
end
|
||||
|
||||
assert resp_body =~ "Authentication required"
|
||||
test "redirects to '/authenticate' if not authenticated", %{conn: conn} do
|
||||
conn = get(conn, "/")
|
||||
assert redirected_to(conn) == "/authenticate"
|
||||
end
|
||||
|
||||
@tag token: "grumpycat"
|
||||
|
@ -48,14 +44,10 @@ defmodule LivebookWeb.AuthPlugTest do
|
|||
end
|
||||
|
||||
@tag token: "grumpycat"
|
||||
test "returns authentication error when invalid token is provided in query params",
|
||||
test "redirects to '/authenticate' when invalid token is provided in query params",
|
||||
%{conn: conn} do
|
||||
{_, _, resp_body} =
|
||||
assert_error_sent 401, fn ->
|
||||
get(conn, "/?token=invalid")
|
||||
end
|
||||
|
||||
assert resp_body =~ "Authentication required"
|
||||
conn = get(conn, "/")
|
||||
assert redirected_to(conn) == "/authenticate"
|
||||
end
|
||||
|
||||
@tag token: "grumpycat"
|
||||
|
|
Loading…
Add table
Reference in a new issue