towerops/lib/towerops_web/controllers/api/v1/agents_controller.ex
Graham McIntire 146f5745cf
fix: resolve compilation errors, test failures, and credo issues
- Escape HEEx template braces in GraphQL/API docs with raw(~S[...])
- Fix test assertions for updated marketing copy and UI text
- Extract helper functions in GraphQL resolvers to reduce nesting depth
- Create shared ErrorHelpers module for API controllers
- Fix ETS race condition in brute force whitelist cache for async tests
- Fix property test generators to use ASCII instead of printable unicode
- Add alert_severity helper to site_live/show
- Update accounts fixtures for explicit user confirmation
2026-02-14 12:23:10 -06:00

91 lines
2.5 KiB
Elixir

defmodule ToweropsWeb.Api.V1.AgentsController do
@moduledoc "API controller for agent tokens."
use ToweropsWeb, :controller
import ToweropsWeb.Api.ErrorHelpers, only: [translate_errors: 1]
alias Towerops.Agents
def index(conn, _params) do
organization_id = conn.assigns.current_organization_id
agents =
organization_id
|> Agents.list_organization_agent_tokens()
|> Enum.map(&format_agent/1)
json(conn, %{data: agents})
end
def create(conn, %{"name" => name}) do
organization_id = conn.assigns.current_organization_id
case Agents.create_agent_token(organization_id, name) do
{:ok, agent_token, raw_token} ->
conn
|> put_status(:created)
|> json(%{data: Map.put(format_agent(agent_token), :token, raw_token)})
{:error, changeset} ->
conn
|> put_status(:unprocessable_entity)
|> json(%{errors: translate_errors(changeset)})
end
end
def create(conn, _params) do
conn |> put_status(:bad_request) |> json(%{error: "Missing 'name' parameter"})
end
def show(conn, %{"id" => id}) do
organization_id = conn.assigns.current_organization_id
agent = Agents.get_agent_token!(id)
if agent.organization_id == organization_id do
device_count = Agents.count_assigned_devices(id)
json(conn, %{
data:
agent
|> format_agent()
|> Map.put(:device_count, device_count)
})
else
conn |> put_status(:not_found) |> json(%{error: "Agent not found"})
end
rescue
Ecto.NoResultsError ->
conn |> put_status(:not_found) |> json(%{error: "Agent not found"})
end
def delete(conn, %{"id" => id}) do
organization_id = conn.assigns.current_organization_id
agent = Agents.get_agent_token!(id)
if agent.organization_id == organization_id do
case Agents.delete_agent_token(id) do
{:ok, _} -> conn |> put_status(:no_content) |> send_resp(204, "")
{:error, _} -> conn |> put_status(:unprocessable_entity) |> json(%{error: "Could not delete agent"})
end
else
conn |> put_status(:not_found) |> json(%{error: "Agent not found"})
end
rescue
Ecto.NoResultsError ->
conn |> put_status(:not_found) |> json(%{error: "Agent not found"})
end
defp format_agent(agent) do
%{
id: agent.id,
name: agent.name,
enabled: agent.enabled,
last_seen_at: agent.last_seen_at,
last_ip: agent.last_ip,
metadata: agent.metadata,
inserted_at: agent.inserted_at
}
end
end