package middleware import ( "context" "errors" "net/http" "net/http/httptest" "strings" "testing" "kra/internal/conf" "kra/internal/modules/system/biz" "github.com/gin-gonic/gin" ) type accessControllerStub struct { scopeErr error } func (*accessControllerStub) Authorize(context.Context, uint, string, string) (bool, error) { return true, nil } func (s *accessControllerStub) ContextWithDataScope(ctx context.Context, authorityID, userID uint) (context.Context, error) { if s.scopeErr != nil { return ctx, s.scopeErr } return biz.NewDataScopeContext(ctx, biz.DataScope{UserID: userID, AuthorityID: authorityID, Scope: 1, All: true}), nil } func TestAccessControlFailsClosedWhenDataScopeResolutionFails(t *testing.T) { gin.SetMode(gin.TestMode) engine := gin.New() engine.Use(func(c *gin.Context) { c.Set(claimsKey, &biz.AuthClaims{ID: 7, AuthorityID: 888}) c.Next() }) engine.Use(AccessControl(conf.NewRuntime(nil, &conf.AdminBackend{}), &accessControllerStub{scopeErr: errors.New("database unavailable")})) called := false engine.GET("/protected", func(c *gin.Context) { called = true }) response := httptest.NewRecorder() engine.ServeHTTP(response, httptest.NewRequest(http.MethodGet, "/protected", nil)) if called { t.Fatal("protected handler ran after data-scope resolution failed") } if response.Code != http.StatusOK || !strings.Contains(response.Body.String(), "数据权限解析失败") { t.Fatalf("status=%d body=%s", response.Code, response.Body.String()) } }