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
40 lines
1.6 KiB
Text
40 lines
1.6 KiB
Text
<Layouts.admin flash={@flash}>
|
|
<div class="space-y-6">
|
|
<div>
|
|
<h1 class="text-2xl font-bold text-zinc-900">All Users</h1>
|
|
<p class="text-zinc-600">Manage system users</p>
|
|
</div>
|
|
|
|
<div class="bg-white rounded-lg border border-zinc-200">
|
|
<.table id="users" rows={@users}>
|
|
<:col :let={user} label="Email">{user.email}</:col>
|
|
<:col :let={user} label="Superuser">{if user.is_superuser, do: "Yes", else: "No"}</:col>
|
|
<:col :let={user} label="Organizations">{length(user.organizations)}</:col>
|
|
<:col :let={user} label="Joined">{Calendar.strftime(user.inserted_at, "%Y-%m-%d")}</:col>
|
|
<:col :let={user} label="">
|
|
<div class="flex gap-2">
|
|
<form action={~p"/admin/impersonate/#{user.id}"} method="post">
|
|
<input type="hidden" name="_csrf_token" value={Phoenix.Controller.get_csrf_token()} />
|
|
<button
|
|
type="submit"
|
|
disabled={user.is_superuser}
|
|
class="text-sm text-blue-600 hover:text-blue-800 disabled:text-zinc-400 disabled:cursor-not-allowed"
|
|
>
|
|
Impersonate
|
|
</button>
|
|
</form>
|
|
<button
|
|
phx-click="delete_user"
|
|
phx-value-id={user.id}
|
|
data-confirm="Are you sure you want to delete this user?"
|
|
disabled={user.is_superuser}
|
|
class="text-sm text-red-600 hover:text-red-800 disabled:text-zinc-400 disabled:cursor-not-allowed"
|
|
>
|
|
Delete
|
|
</button>
|
|
</div>
|
|
</:col>
|
|
</.table>
|
|
</div>
|
|
</div>
|
|
</Layouts.admin>
|