refactor(api): rename auth/whoami to users/info and simplify response

Rename endpoint from /auth/whoami to /users/info to align with
ez-contract schema. Simplify WhoamiResponse by removing:
- Realtime stats (requests, tokens, qps, rate_limited)
- Key-specific fields (allow_ips, deny_ips, expires_at, model_limits,
  quota fields, usage stats)

The endpoint now returns only essential identity information as
defined in ez-contract/schemas/auth/auth.yaml.

BREAKING CHANGE: /auth/whoami endpoint moved to /users/info with
reduced response fields
This commit is contained in:
2026-01-13 15:57:52 +08:00
parent c990fa6610
commit 7929b2a872
3 changed files with 49 additions and 173 deletions

View File

@@ -97,7 +97,8 @@ func TestAuthHandler_Whoami_InvalidMasterEpoch_Returns401(t *testing.T) {
}
}
func TestAuthHandler_Whoami_KeyResponseIncludesIPRules(t *testing.T) {
// TestAuthHandler_Whoami_KeyResponseFormat tests the key response format per contract.
func TestAuthHandler_Whoami_KeyResponseFormat(t *testing.T) {
handler, db, mr := newAuthHandler(t)
token := "sk-live-valid"
@@ -131,9 +132,9 @@ func TestAuthHandler_Whoami_KeyResponseIncludesIPRules(t *testing.T) {
r := gin.New()
r.Use(middleware.ResponseEnvelope())
r.GET("/auth/whoami", handler.Whoami)
r.GET("/users/info", handler.Whoami)
req := httptest.NewRequest(http.MethodGet, "/auth/whoami", nil)
req := httptest.NewRequest(http.MethodGet, "/users/info", nil)
req.Header.Set("Authorization", "Bearer "+token)
rr := httptest.NewRecorder()
r.ServeHTTP(rr, req)
@@ -150,14 +151,25 @@ func TestAuthHandler_Whoami_KeyResponseIncludesIPRules(t *testing.T) {
if env.Message != "success" {
t.Fatalf("expected message=success, got %q", env.Message)
}
if resp["allow_ips"] != "1.2.3.4" {
t.Fatalf("expected allow_ips, got %v", resp["allow_ips"])
// Verify contract-defined fields are present
if resp["type"] != "key" {
t.Fatalf("expected type=key, got %v", resp["type"])
}
if resp["deny_ips"] != "5.6.7.0/24" {
t.Fatalf("expected deny_ips, got %v", resp["deny_ips"])
if resp["scopes"] != "chat:write" {
t.Fatalf("expected scopes=chat:write, got %v", resp["scopes"])
}
if got, ok := resp["expires_at"].(float64); !ok || int64(got) != expiresAt {
t.Fatalf("expected expires_at=%d, got %v", expiresAt, resp["expires_at"])
if resp["issued_by"] != "master" {
t.Fatalf("expected issued_by=master, got %v", resp["issued_by"])
}
// Verify removed fields are not present (per contract)
if _, exists := resp["allow_ips"]; exists {
t.Fatalf("allow_ips should not be in response per contract")
}
if _, exists := resp["deny_ips"]; exists {
t.Fatalf("deny_ips should not be in response per contract")
}
if _, exists := resp["expires_at"]; exists {
t.Fatalf("expires_at should not be in response per contract")
}
}