feat(server): session-based auth plug + login controller/template

This commit is contained in:
Carsten 2026-04-21 22:51:11 +02:00
parent 3123743c1c
commit 4538945b85
4 changed files with 95 additions and 0 deletions

View file

@ -0,0 +1,28 @@
defmodule ServerWeb.AuthController do
use ServerWeb, :controller
def login(conn, _params) do
render(conn, :login, error: nil, layout: false)
end
def create(conn, %{"password" => password}) do
case Server.Auth.verify_password(password) do
:ok ->
conn
|> configure_session(renew: true)
|> put_session(:authenticated, true)
|> redirect(to: "/")
:error ->
conn
|> put_status(:unauthorized)
|> render(:login, error: "Incorrect password.", layout: false)
end
end
def delete(conn, _params) do
conn
|> configure_session(drop: true)
|> redirect(to: "/login")
end
end

View file

@ -0,0 +1,5 @@
defmodule ServerWeb.AuthHTML do
use ServerWeb, :html
embed_templates "auth_html/*"
end

View file

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="csrf-token" content={Phoenix.Controller.get_csrf_token()} />
<title>Sign in · Proxmox Monitor</title>
<link phx-track-static rel="stylesheet" href={~p"/assets/app.css"} />
</head>
<body class="bg-white">
<div class="min-h-screen flex items-center justify-center">
<div class="max-w-sm w-full space-y-6 p-6 border border-zinc-200 rounded-lg shadow">
<h1 class="text-xl font-semibold text-zinc-800">Proxmox Monitor</h1>
<%= if @error do %>
<p class="text-sm text-red-600">{@error}</p>
<% end %>
<form method="post" action="/login" class="space-y-4">
<input type="hidden" name="_csrf_token" value={Phoenix.Controller.get_csrf_token()} />
<label class="block">
<span class="text-sm text-zinc-700">Password</span>
<input
name="password"
type="password"
required
autofocus
class="mt-1 block w-full rounded-md border-zinc-300 focus:border-zinc-400 focus:ring-0"
/>
</label>
<button
type="submit"
class="w-full rounded-md bg-zinc-900 text-white py-2 hover:bg-zinc-700"
>
Sign in
</button>
</form>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,19 @@
defmodule ServerWeb.Plugs.RequireAuth do
@moduledoc "Redirects to /login unless the session is authenticated."
import Plug.Conn
import Phoenix.Controller
def init(opts), do: opts
def call(conn, _opts) do
if get_session(conn, :authenticated) do
conn
else
conn
|> put_flash(:error, "Please sign in.")
|> redirect(to: "/login")
|> halt()
end
end
end