package middleware import ( "net/http" "net/http/httptest" "testing" "time" "github.com/gin-gonic/gin" "filecodebox/internal/response" ) const testSecret = "unit-test-secret-0123456789abcdef" func init() { gin.SetMode(gin.TestMode) } func TestSignAndVerifyAdminToken(t *testing.T) { token, expiresAt, err := SignAdminToken(testSecret, time.Hour) if err != nil { t.Fatalf("签发失败: %v", err) } if expiresAt.Before(time.Now()) { t.Fatal("过期时间不合理") } claims, err := VerifyAdminToken(testSecret, token) if err != nil { t.Fatalf("校验失败: %v", err) } if !claims.IsAdmin { t.Fatal("is_admin 应为 true") } } func TestVerifyTamperedToken(t *testing.T) { token, _, _ := SignAdminToken(testSecret, time.Hour) claims, err := VerifyAdminToken(testSecret+"-wrong", token) if err == nil || claims != nil { t.Fatal("密钥不匹配应校验失败") } // 篡改 payload tampered := token[:len(token)-3] + "abc" if _, err := VerifyAdminToken(testSecret, tampered); err == nil { t.Fatal("篡改的 token 应校验失败") } // 非 HMAC 算法拒绝 algNone := "eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJpc19hZG1pbiI6dHJ1ZX0." if _, err := VerifyAdminToken(testSecret, algNone); err == nil { t.Fatal("none 算法应被拒绝") } } func TestAdminAuthMiddleware(t *testing.T) { r := gin.New() r.GET("/protected", AdminAuth(func() string { return testSecret }), func(c *gin.Context) { response.OK(c, gin.H{"ok": true}) }) // 无 token → 401 w := httptest.NewRecorder() r.ServeHTTP(w, httptest.NewRequest("GET", "/protected", nil)) if w.Code != http.StatusUnauthorized { t.Fatalf("无 token 应 401: %d", w.Code) } // 有效 token → 200 token, _, _ := SignAdminToken(testSecret, time.Hour) w = httptest.NewRecorder() req := httptest.NewRequest("GET", "/protected", nil) req.Header.Set("Authorization", "Bearer "+token) r.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Fatalf("有效 token 应 200: %d %s", w.Code, w.Body.String()) } // 过期 token → 401 expired, _, _ := SignAdminToken(testSecret, -time.Minute) w = httptest.NewRecorder() req = httptest.NewRequest("GET", "/protected", nil) req.Header.Set("Authorization", "Bearer "+expired) r.ServeHTTP(w, req) if w.Code != http.StatusUnauthorized { t.Fatalf("过期 token 应 401: %d", w.Code) } }