feat(usage): limit read-only request history

This commit is contained in:
2026-08-19 18:55:35 +08:00
parent a35854e018
commit 2933d077b3
8 changed files with 68 additions and 18 deletions
+10 -3
View File
@@ -92,11 +92,18 @@ func TestReadOnlyResourceReturnsRealDataWithoutSecrets(t *testing.T) {
usage := managementCallRequest(t, app, ManagementRequest{
Method: http.MethodGet,
Path: resourceBase + resourceUI,
Query: url.Values{"view": {"usage"}},
Query: url.Values{"view": {"usage"}, "page": {"9"}, "page_size": {"100"}},
})
if usage.StatusCode != http.StatusOK || strings.Contains(string(usage.Body), `"api_key":"000000"`) {
t.Fatalf("read-only usage exposed a historical key: status=%d body=%s", usage.StatusCode, usage.Body)
}
var readOnlyPayload usageListResponse
if err := json.Unmarshal(usage.Body, &readOnlyPayload); err != nil {
t.Fatal(err)
}
if readOnlyPayload.Pagination.Page != 1 || readOnlyPayload.Pagination.PageSize != 50 {
t.Fatalf("read-only usage pagination=%+v", readOnlyPayload.Pagination)
}
invalid := managementCallRequest(t, app, ManagementRequest{
Method: http.MethodGet,
@@ -565,7 +572,7 @@ func TestUsageResourceServesFeatureModules(t *testing.T) {
if pageResponse.StatusCode != http.StatusOK || !strings.Contains(page, `data-view="logs">日志`) {
t.Fatalf("unexpected UI response: status=%d", pageResponse.StatusCode)
}
for _, feature := range []string{`<body class="read-only">`, `id="demo-perspective" class="demo-perspective hidden"`, `data-perspective="admin">管理员示教`, `data-perspective="user">普通用户视角`, `data-view="stats">统计`, `data-view="users">用户`, `id="view-users" class="view admin-only"`, `id="quota-chart"`, `id="page-buttons"`, `id="user-usage"`, `id="usage-filter-panel" class="usage-filter-panel"`, `id="editor-quota"`, `id="billing-ledger"`, `id="key-management" class="user-management"`, `id="reset-all-billing"`, `id="key-rows" class="user-card-grid"`, `class="surface price-panel price-layout"`, `src="./ui-config.js"`, `type="module" src="./app/main.js"`, `href="./styles/base.css"`, `href="./styles/keys.css"`, `href="./styles/usage.css"`, `href="./styles/pricing.css"`} {
for _, feature := range []string{`<body class="read-only">`, `id="demo-perspective" class="demo-perspective hidden"`, `data-perspective="admin">管理员示教`, `data-perspective="user">普通用户视角`, `data-view="stats">统计`, `data-view="users">用户`, `id="view-users" class="view admin-only"`, `id="quota-chart"`, `id="page-buttons" class="page-buttons admin-only"`, `id="user-usage"`, `id="usage-filter-panel" class="usage-filter-panel admin-only"`, `id="refresh" class="admin-only"`, `id="editor-quota"`, `id="billing-ledger"`, `id="key-management" class="user-management"`, `id="reset-all-billing"`, `id="key-rows" class="user-card-grid"`, `class="surface price-panel price-layout"`, `src="./ui-config.js"`, `type="module" src="./app/main.js"`, `href="./styles/base.css"`, `href="./styles/keys.css"`, `href="./styles/usage.css"`, `href="./styles/pricing.css"`} {
if !strings.Contains(page, feature) {
t.Fatalf("UI does not contain HTML feature %q", feature)
}
@@ -594,7 +601,7 @@ func TestUsageResourceServesFeatureModules(t *testing.T) {
}
javascript.Write(response.Body)
}
for _, feature := range []string{"initializeRuntime", "dataFetch", "isManagementAuthorized", "pageSize = 100", `row.setAttribute("role", "button")`, "syncLongSectionVisibility", `return "compact"`, "isCompactEndpoint(record.endpoint)", `identity.title = "点击复制 Key"`, `return "自由选择"`, "剩余额度", `document.body.classList.toggle("read-only"`, `删除 ${model} 的真实价格配置`, `发现 ${changed.length} 个已关联价格发生变化`} {
for _, feature := range []string{"initializeRuntime", "dataFetch", "isManagementAuthorized", "adminPageSize = 100", "userPageSize = 50", `row.setAttribute("role", "button")`, "syncLongSectionVisibility", `return "compact"`, "isCompactEndpoint(record.endpoint)", `identity.title = "点击复制 Key"`, `return "自由选择"`, "剩余额度", `document.body.classList.toggle("read-only"`, `删除 ${model} 的真实价格配置`, `发现 ${changed.length} 个已关联价格发生变化`} {
if !strings.Contains(javascript.String(), feature) {
t.Fatalf("UI modules do not contain feature %q", feature)
}
+2 -1
View File
@@ -47,7 +47,8 @@ func (a *App) readOnlyResponse(query url.Values) ManagementResponse {
}
func (a *App) readOnlyUsageResponse(query url.Values) ManagementResponse {
response := a.usageResponse(query)
limited := url.Values{"page": {"1"}, "page_size": {"50"}}
response := a.usageResponse(limited)
if response.StatusCode != http.StatusOK {
return response
}