Implement comprehensive admin interface allowing designated superusers to view all users and organizations, impersonate users for debugging, and perform administrative operations. All superuser actions are tracked in audit logs for compliance. Features: - Superuser authentication with dedicated admin routes at /admin - User impersonation with session state preservation - Admin dashboard with system statistics - User and organization management interfaces - Comprehensive audit logging with IP tracking - Visual impersonation banner with exit capability - Security controls preventing self-impersonation and superuser-to-superuser impersonation Database: - Add is_superuser boolean field to users table - Create audit_logs table for tracking sensitive operations - Set graham@mcintire.me as initial superuser
141 lines
4.1 KiB
Elixir
141 lines
4.1 KiB
Elixir
defmodule ToweropsWeb.Router do
|
|
use ToweropsWeb, :router
|
|
|
|
import Phoenix.LiveDashboard.Router
|
|
import ToweropsWeb.UserAuth
|
|
|
|
pipeline :browser do
|
|
plug :accepts, ["html"]
|
|
plug :fetch_session
|
|
plug :fetch_live_flash
|
|
plug :put_root_layout, html: {ToweropsWeb.Layouts, :root}
|
|
plug :protect_from_forgery
|
|
plug :put_secure_browser_headers
|
|
plug :fetch_current_scope_for_user
|
|
end
|
|
|
|
pipeline :api do
|
|
plug :accepts, ["json"]
|
|
end
|
|
|
|
# Health check endpoint for Kubernetes probes (no authentication required)
|
|
scope "/", ToweropsWeb do
|
|
get "/health", HealthController, :index
|
|
end
|
|
|
|
scope "/", ToweropsWeb do
|
|
pipe_through :browser
|
|
|
|
get "/", PageController, :home
|
|
end
|
|
|
|
# Other scopes may use custom stacks.
|
|
# scope "/api", ToweropsWeb do
|
|
# pipe_through :api
|
|
# end
|
|
|
|
# Enable LiveDashboard in production with authentication
|
|
scope "/dashboard" do
|
|
pipe_through [:browser, :require_authenticated_user]
|
|
|
|
live_dashboard "/", metrics: ToweropsWeb.Telemetry, ecto_repos: [Towerops.Repo]
|
|
end
|
|
|
|
# Enable Swoosh mailbox preview in development
|
|
if Application.compile_env(:towerops, :dev_routes) do
|
|
scope "/dev" do
|
|
pipe_through :browser
|
|
|
|
forward "/mailbox", Plug.Swoosh.MailboxPreview
|
|
end
|
|
end
|
|
|
|
## Authentication routes
|
|
|
|
scope "/", ToweropsWeb do
|
|
pipe_through [:browser, :redirect_if_user_is_authenticated]
|
|
|
|
get "/users/register", UserRegistrationController, :new
|
|
post "/users/register", UserRegistrationController, :create
|
|
end
|
|
|
|
scope "/", ToweropsWeb do
|
|
pipe_through [:browser, :require_authenticated_user]
|
|
|
|
get "/users/settings", UserSettingsController, :edit
|
|
put "/users/settings", UserSettingsController, :update
|
|
get "/users/settings/confirm-email/:token", UserSettingsController, :confirm_email
|
|
end
|
|
|
|
scope "/", ToweropsWeb do
|
|
pipe_through [:browser]
|
|
|
|
get "/users/log-in", UserSessionController, :new
|
|
get "/users/log-in/:token", UserSessionController, :confirm
|
|
post "/users/log-in", UserSessionController, :create
|
|
delete "/users/log-out", UserSessionController, :delete
|
|
end
|
|
|
|
## Admin routes (superuser only)
|
|
|
|
scope "/", ToweropsWeb do
|
|
pipe_through [:browser, :require_authenticated_user, :require_superuser]
|
|
|
|
post "/admin/impersonate/:user_id", AdminController, :start_impersonate
|
|
delete "/admin/impersonate", AdminController, :stop_impersonate
|
|
end
|
|
|
|
live_session :require_superuser,
|
|
on_mount: [
|
|
{ToweropsWeb.UserAuth, :require_authenticated_user},
|
|
{ToweropsWeb.UserAuth, :require_superuser}
|
|
] do
|
|
scope "/admin", ToweropsWeb.Admin do
|
|
pipe_through [:browser, :require_authenticated_user, :require_superuser]
|
|
|
|
live "/", DashboardLive, :index
|
|
live "/users", UserLive.Index, :index
|
|
live "/organizations", OrgLive.Index, :index
|
|
end
|
|
end
|
|
|
|
## Organization routes
|
|
|
|
live_session :require_authenticated_user,
|
|
on_mount: [{ToweropsWeb.UserAuth, :require_authenticated_user}] do
|
|
scope "/", ToweropsWeb do
|
|
pipe_through [:browser, :require_authenticated_user]
|
|
|
|
live "/orgs", OrgLive.Index, :index
|
|
live "/orgs/new", OrgLive.New, :new
|
|
end
|
|
end
|
|
|
|
live_session :require_authenticated_user_and_organization,
|
|
on_mount: [
|
|
{ToweropsWeb.UserAuth, :require_authenticated_user},
|
|
{ToweropsWeb.UserAuth, :load_current_organization}
|
|
] do
|
|
scope "/orgs/:org_slug", ToweropsWeb do
|
|
pipe_through [:browser, :require_authenticated_user, :load_current_organization]
|
|
|
|
live "/", DashboardLive, :index
|
|
|
|
# Site routes
|
|
live "/sites", SiteLive.Index, :index
|
|
live "/sites/new", SiteLive.Form, :new
|
|
live "/sites/:id", SiteLive.Show, :show
|
|
live "/sites/:id/edit", SiteLive.Form, :edit
|
|
|
|
# Equipment routes
|
|
live "/equipment", EquipmentLive.Index, :index
|
|
live "/equipment/new", EquipmentLive.Form, :new
|
|
live "/equipment/:id", EquipmentLive.Show, :show
|
|
live "/equipment/:id/edit", EquipmentLive.Form, :edit
|
|
live "/equipment/:id/graph/:sensor_type", GraphLive.Show, :show
|
|
|
|
# Alert routes
|
|
live "/alerts", AlertLive.Index, :index
|
|
end
|
|
end
|
|
end
|