Files
sure/app/controllers/settings/llm_usages_controller.rb
Andrew B f8615f0e9c fix(settings): require admin for family-wide advanced settings pages (#2403)
The "Advanced" settings section is gated to admins in the navigation, but
the controllers exposing family-wide data performed no server-side
authorization — any authenticated user could reach them by navigating
directly to the URL.

Add `before_action :require_admin!` to the controllers that expose
family-wide data:
- Settings::AiPromptsController (family AI assistant config)
- Settings::LlmUsagesController (family LLM usage/billing)

This mirrors the existing guards on Settings::ProvidersController and
Settings::HostingsController. Non-admins are redirected with the standard
"Only admins can perform this action" message (403 for turbo_stream/json).

API key and MCP token management are intentionally left open: both are
user-scoped self-management. Their actions are already scoped to
Current.user, and any signed-in user (not just admins) can create an API
key or authorize an MCP client, so gating them would leave members unable
to view or revoke their own credentials.

Adds controller tests covering admin-only access for the family-wide pages
(member and guest rejected) and member self-service access for the API key
and MCP pages.
2026-07-21 09:01:45 +02:00

37 lines
1.1 KiB
Ruby

class Settings::LlmUsagesController < ApplicationController
layout "settings"
before_action :require_admin!
def show
@breadcrumbs = [
[ t("breadcrumbs.home"), root_path ],
[ t("breadcrumbs.llm_usage"), nil ]
]
@family = Current.family
# Get date range from params or default to last 30 days
@end_date = safe_parse_date(params[:end_date]) || Date.today
@start_date = safe_parse_date(params[:start_date]) || (@end_date - 30.days)
if @start_date > @end_date
@start_date, @end_date = @end_date - 30.days, @end_date
end
# Get usage data
@llm_usages = @family.llm_usages
.for_date_range(@start_date.beginning_of_day, @end_date.end_of_day)
.recent
.limit(100)
# Get statistics
@statistics = LlmUsage.statistics_for_family(@family, start_date: @start_date.beginning_of_day, end_date: @end_date.end_of_day)
end
private
def safe_parse_date(s)
Date.iso8601(s)
rescue ArgumentError, TypeError
nil
end
end