mirror of
https://github.com/EZ-Api/ez-api.git
synced 2026-01-13 17:47:51 +00:00
feat(api): enhance whoami endpoint with realtime stats and extended key info
Add realtime statistics (requests, tokens, QPS, rate limiting) to whoami response for both master and key authentication types. Extend key response with additional fields including master name, model limits, quota tracking, and usage statistics. - Inject StatsService into AuthHandler for realtime stats retrieval - Add WhoamiRealtimeView struct for realtime statistics - Include admin permissions field in admin response - Add comprehensive key metadata (quotas, model limits, usage stats) - Add test for expired key returning 401 Unauthorized
This commit is contained in:
@@ -40,7 +40,8 @@ func newAuthHandler(t *testing.T) (*AuthHandler, *gorm.DB, *miniredis.Miniredis)
|
||||
rdb := redis.NewClient(&redis.Options{Addr: mr.Addr()})
|
||||
|
||||
masterService := service.NewMasterService(db)
|
||||
handler := NewAuthHandler(db, rdb, adminService, masterService)
|
||||
statsService := service.NewStatsService(rdb)
|
||||
handler := NewAuthHandler(db, rdb, adminService, masterService, statsService)
|
||||
return handler, db, mr
|
||||
}
|
||||
|
||||
@@ -152,3 +153,56 @@ func TestAuthHandler_Whoami_KeyResponseIncludesIPRules(t *testing.T) {
|
||||
t.Fatalf("expected expires_at=%d, got %v", expiresAt, resp["expires_at"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthHandler_Whoami_ExpiredKey_Returns401(t *testing.T) {
|
||||
handler, db, mr := newAuthHandler(t)
|
||||
|
||||
token := "sk-live-expired"
|
||||
hash := tokenhash.HashToken(token)
|
||||
// Set expiration to 1 hour ago
|
||||
expiresAt := time.Now().Add(-time.Hour).Unix()
|
||||
|
||||
mr.HSet("auth:token:"+hash, "master_id", "1")
|
||||
mr.HSet("auth:token:"+hash, "issued_at_epoch", "1")
|
||||
mr.HSet("auth:token:"+hash, "status", "active")
|
||||
mr.HSet("auth:token:"+hash, "group", "default")
|
||||
mr.HSet("auth:token:"+hash, "expires_at", fmt.Sprintf("%d", expiresAt))
|
||||
mr.HSet("auth:master:1", "epoch", "1")
|
||||
mr.HSet("auth:master:1", "status", "active")
|
||||
|
||||
// Create key in DB
|
||||
key := &model.Key{
|
||||
MasterID: 1,
|
||||
TokenHash: hash,
|
||||
Group: "default",
|
||||
Scopes: "chat:write",
|
||||
DefaultNamespace: "default",
|
||||
Namespaces: "default",
|
||||
Status: "active",
|
||||
IssuedAtEpoch: 1,
|
||||
IssuedBy: "master",
|
||||
}
|
||||
if err := db.Create(key).Error; err != nil {
|
||||
t.Fatalf("create key: %v", err)
|
||||
}
|
||||
|
||||
r := gin.New()
|
||||
r.GET("/auth/whoami", handler.Whoami)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/auth/whoami", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
rr := httptest.NewRecorder()
|
||||
r.ServeHTTP(rr, req)
|
||||
|
||||
if rr.Code != http.StatusUnauthorized {
|
||||
t.Fatalf("expected 401 for expired key, got %d body=%s", rr.Code, rr.Body.String())
|
||||
}
|
||||
|
||||
var resp map[string]any
|
||||
if err := json.Unmarshal(rr.Body.Bytes(), &resp); err != nil {
|
||||
t.Fatalf("decode response: %v", err)
|
||||
}
|
||||
if resp["error"] != "token has expired" {
|
||||
t.Fatalf("expected 'token has expired' error, got %v", resp["error"])
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user