Allow superadmins to view and edit any agent regardless of org

The admin agents page links to /agents/:id but the show and edit
pages were scoped to the current user's organization, causing 404s
for agents belonging to other orgs.
This commit is contained in:
Graham McIntire 2026-02-10 12:19:20 -06:00
parent c1fca6276a
commit c066399e18
No known key found for this signature in database
3 changed files with 55 additions and 4 deletions

View file

@ -11,9 +11,15 @@ defmodule ToweropsWeb.AgentLive.Edit do
@impl true
def mount(%{"id" => id}, _session, socket) do
organization = socket.assigns.current_scope.organization
current_user = socket.assigns.current_scope.user
# Get agent token and verify it belongs to this organization
agent_token = Towerops.Repo.get_by!(AgentToken, id: id, organization_id: organization.id)
# Superadmins can edit any agent; regular users only their org's agents
agent_token =
if current_user.is_superuser do
Towerops.Repo.get!(AgentToken, id)
else
Towerops.Repo.get_by!(AgentToken, id: id, organization_id: organization.id)
end
changeset = AgentToken.update_changeset(agent_token, %{})

View file

@ -12,10 +12,10 @@ defmodule ToweropsWeb.AgentLive.Show do
agent_token = Agents.get_agent_token!(id)
current_user = socket.assigns.current_scope.user
# Verify access: agent must belong to this org OR be a cloud poller (visible to superadmin)
# Verify access: agent must belong to this org, or superadmin can view any agent
has_access =
agent_token.organization_id == organization.id ||
(agent_token.is_cloud_poller && current_user.is_superuser)
current_user.is_superuser
if !has_access do
raise Ecto.NoResultsError, queryable: Towerops.Agents.AgentToken

View file

@ -493,4 +493,49 @@ defmodule ToweropsWeb.AgentLiveTest do
end)
end
end
describe "Show - Superadmin Cross-Org Access" do
setup %{user: user} do
Towerops.Repo.update!(Ecto.Changeset.change(user, %{is_superuser: true}))
:ok
end
test "superadmin can view agent from another organization", %{conn: conn, organization: organization, user: user} do
{:ok, other_org} = Towerops.Organizations.create_organization(%{name: "Other Org"}, user.id, bypass_limits: true)
{:ok, agent_token, _token} = Agents.create_agent_token(other_org.id, "Other Org Agent")
conn = Plug.Test.init_test_session(conn, %{"current_organization_id" => organization.id})
{:ok, _view, html} = live(conn, ~p"/agents/#{agent_token.id}")
assert html =~ "Other Org Agent"
end
test "superadmin can edit agent from another organization", %{conn: conn, organization: organization, user: user} do
{:ok, other_org} = Towerops.Organizations.create_organization(%{name: "Other Org"}, user.id, bypass_limits: true)
{:ok, agent_token, _token} = Agents.create_agent_token(other_org.id, "Other Org Agent")
conn = Plug.Test.init_test_session(conn, %{"current_organization_id" => organization.id})
{:ok, _view, html} = live(conn, ~p"/agents/#{agent_token.id}/edit")
assert html =~ "Edit Agent"
assert html =~ "Other Org Agent"
end
end
describe "Show - Regular User Cross-Org Access" do
test "regular user cannot view agent from another organization", %{conn: conn, organization: organization, user: user} do
{:ok, other_org} = Towerops.Organizations.create_organization(%{name: "Other Org"}, user.id, bypass_limits: true)
{:ok, agent_token, _token} = Agents.create_agent_token(other_org.id, "Other Org Agent")
conn = Plug.Test.init_test_session(conn, %{"current_organization_id" => organization.id})
capture_log(fn ->
assert_raise Ecto.NoResultsError, fn ->
live(conn, ~p"/agents/#{agent_token.id}")
end
end)
end
end
end