towerops/lib/towerops_web/live/site_live/show.html.heex
Graham McIntire 806b293ead
Fix impersonation to show correct user data and banner
Two issues were preventing impersonation from working correctly:

1. Templates were not passing current_scope to Layouts.authenticated,
   so the impersonation banner never displayed.

2. fetch_current_scope_for_user was looking up the user from the
   session token, which always pointed to the superuser. This caused
   the superuser to see their own organizations and equipment instead
   of the impersonated user's data.

Changes:
- Pass current_scope={@current_scope} to all Layouts.authenticated calls
- Store target_user_id in session during impersonation
- Fetch target user directly from database using target_user_id
- Update both fetch_current_scope_for_user (for controllers) and
  mount_current_scope (for LiveViews) to properly handle impersonation
- Clean up target_user_id from session when impersonation ends

Now when a superuser impersonates a user, they correctly see:
- The impersonation banner at the top with exit link
- The target user's organizations and equipment
- All data scoped to the impersonated user
2026-01-06 13:22:13 -06:00

127 lines
5 KiB
Text

<Layouts.authenticated
flash={@flash}
current_scope={@current_scope}
current_organization={@current_organization}
active_page="sites"
>
<.header>
{@page_title}
<:subtitle>{@site.location}</:subtitle>
<:actions>
<.button navigate={~p"/orgs/#{@current_organization.slug}/sites/#{@site.id}/edit"}>
<.icon name="hero-pencil" class="h-4 w-4" /> Edit
</.button>
</:actions>
</.header>
<div class="mt-8 grid gap-6 md:grid-cols-2">
<div>
<h3 class="text-lg font-semibold mb-4 text-zinc-900 dark:text-zinc-100">Site Details</h3>
<dl class="space-y-4">
<%= if @site.parent_site do %>
<div>
<dt class="text-sm font-medium text-zinc-600 dark:text-zinc-400">Parent Site</dt>
<dd class="mt-1">
<.link
navigate={~p"/orgs/#{@current_organization.slug}/sites/#{@site.parent_site.id}"}
class="text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300"
>
{@site.parent_site.name}
</.link>
</dd>
</div>
<% end %>
<%= if @site.location do %>
<div>
<dt class="text-sm font-medium text-zinc-600 dark:text-zinc-400">Location</dt>
<dd class="mt-1 text-zinc-900 dark:text-zinc-100">{@site.location}</dd>
</div>
<% end %>
<%= if @site.description do %>
<div>
<dt class="text-sm font-medium text-zinc-600 dark:text-zinc-400">Description</dt>
<dd class="mt-1 text-zinc-900 dark:text-zinc-100">{@site.description}</dd>
</div>
<% end %>
</dl>
<%= if @site.child_sites != [] do %>
<div class="mt-6">
<h4 class="text-sm font-semibold mb-3 text-zinc-900 dark:text-zinc-100">Child Sites</h4>
<ul class="space-y-2">
<li :for={child <- @site.child_sites}>
<.link
navigate={~p"/orgs/#{@current_organization.slug}/sites/#{child.id}"}
class="text-sm text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300"
>
{child.name}
</.link>
</li>
</ul>
</div>
<% end %>
</div>
<div>
<div class="flex justify-between items-center mb-4">
<h3 class="text-lg font-semibold text-zinc-900 dark:text-zinc-100">Equipment</h3>
<.button
navigate={~p"/orgs/#{@current_organization.slug}/equipment/new?site_id=#{@site.id}"}
variant="primary"
>
<.icon name="hero-plus" class="h-4 w-4" /> Add Equipment
</.button>
</div>
<%= if @equipment == [] do %>
<div class="rounded-lg border-2 border-dashed border-zinc-300 bg-zinc-50 p-8 text-center dark:border-zinc-700 dark:bg-zinc-900">
<.icon name="hero-server" class="mx-auto h-12 w-12 text-zinc-400 dark:text-zinc-600" />
<h4 class="mt-4 text-base font-semibold text-zinc-900 dark:text-zinc-100">
Add your first device
</h4>
<p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
Start monitoring by adding network equipment to this site.
</p>
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
You can add routers, switches, servers, or any device with an IP address.
</p>
<div class="mt-6">
<.button
navigate={~p"/orgs/#{@current_organization.slug}/equipment/new?site_id=#{@site.id}"}
variant="primary"
>
<.icon name="hero-plus" class="h-5 w-5" /> Add Equipment
</.button>
</div>
</div>
<% else %>
<div class="space-y-3">
<div
:for={eq <- @equipment}
class="flex items-center justify-between rounded-lg border border-zinc-200 bg-white p-4 dark:border-zinc-800 dark:bg-zinc-900"
>
<div>
<p class="font-medium text-zinc-900 dark:text-zinc-100">{eq.name}</p>
<p class="text-sm text-zinc-600 dark:text-zinc-400">{eq.ip_address}</p>
</div>
<div class="flex items-center gap-3">
<span class={[
"inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium",
eq.status == :up &&
"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200",
eq.status == :down && "bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200",
eq.status == :unknown &&
"bg-zinc-100 text-zinc-800 dark:bg-zinc-800 dark:text-zinc-200"
]}>
{eq.status |> to_string() |> String.upcase()}
</span>
<.button navigate={~p"/orgs/#{@current_organization.slug}/equipment/#{eq.id}"}>
View
</.button>
</div>
</div>
</div>
<% end %>
</div>
</div>
</Layouts.authenticated>