diff --git a/ingress/ingress.go b/ingress/ingress.go index a325271a7e7..915fd94b46f 100644 --- a/ingress/ingress.go +++ b/ingress/ingress.go @@ -312,7 +312,8 @@ func validateIngress(ingress []config.UnvalidatedIngressRule, defaults OriginReq } var handlers []middleware.Handler - if access := r.OriginRequest.Access; access != nil { + access := &cfg.Access + if access.Required || access.TeamName != "" || len(access.AudTag) > 0 { if err := validateAccessConfiguration(access); err != nil { return Ingress{}, err } diff --git a/ingress/ingress_test.go b/ingress/ingress_test.go index 109cb3530e2..7c95465b977 100644 --- a/ingress/ingress_test.go +++ b/ingress/ingress_test.go @@ -555,7 +555,7 @@ func TestSingleOriginServices(t *testing.T) { flagSet.String("unix-socket", "", "") cliCtx := cli.NewContext(cli.NewApp(), flagSet, nil) for i := 0; i < len(params); i += 2 { - cliCtx.Set(params[i], params[i+1]) + require.NoError(t, cliCtx.Set(params[i], params[i+1])) } return cliCtx @@ -605,7 +605,7 @@ func TestSingleOriginServices(t *testing.T) { if test.err != nil { return } - require.Equal(t, 1, len(ingress.Rules)) + require.Len(t, ingress.Rules, 1) rule := ingress.Rules[0] require.Equal(t, test.expectedService, rule.Service) }) @@ -626,7 +626,7 @@ func TestSingleOriginServices_URL(t *testing.T) { flagSet := flag.NewFlagSet(t.Name(), flag.PanicOnError) flagSet.String("url", "", "") cliCtx := cli.NewContext(cli.NewApp(), flagSet, nil) - cliCtx.Set(param, value) + require.NoError(t, cliCtx.Set(param, value)) return cliCtx } @@ -636,7 +636,7 @@ func TestSingleOriginServices_URL(t *testing.T) { url := urlMustParse(test + host) ingress, err := parseCLIIngress(newCli("url", url.String()), false) require.NoError(t, err) - require.Equal(t, 1, len(ingress.Rules)) + require.Len(t, ingress.Rules, 1) rule := ingress.Rules[0] require.Equal(t, &httpService{url: url}, rule.Service) }) @@ -648,7 +648,7 @@ func TestSingleOriginServices_URL(t *testing.T) { url := urlMustParse(test + host) ingress, err := parseCLIIngress(newCli("url", url.String()), false) require.NoError(t, err) - require.Equal(t, 1, len(ingress.Rules)) + require.Len(t, ingress.Rules, 1) rule := ingress.Rules[0] require.Equal(t, newTCPOverWSService(url), rule.Service) }) @@ -712,7 +712,7 @@ func TestFindMatchingRule(t *testing.T) { for _, test := range tests { _, ruleIndex := ingress.FindMatchingRule(test.host, test.path) - assert.Equal(t, test.wantRuleIndex, ruleIndex, fmt.Sprintf("Expect host=%s, path=%s to match rule %d, got %d", test.host, test.path, test.wantRuleIndex, ruleIndex)) + assert.Equal(t, test.wantRuleIndex, ruleIndex, "Expect host=%s, path=%s to match rule %d, got %d", test.host, test.path, test.wantRuleIndex, ruleIndex) } } @@ -832,6 +832,103 @@ func TestParseAccessConfig(t *testing.T) { } } +func TestParseIngressAccessConfig(t *testing.T) { + t.Parallel() + + globalAccess := config.AccessConfig{ + Required: true, + TeamName: "global-team", + AudTag: []string{"global-aud"}, + Environment: "global-environment", + } + ruleAccess := config.AccessConfig{ + Required: true, + TeamName: "rule-team", + AudTag: []string{"rule-aud"}, + Environment: "rule-environment", + } + + tests := []struct { + name string + globalAccess *config.AccessConfig + ruleAccess *config.AccessConfig + expectedHandlers []int + expectedAccess []config.AccessConfig + expectedError string + }{ + { + name: "global access applies to every rule", + globalAccess: &globalAccess, + expectedHandlers: []int{1, 1}, + expectedAccess: []config.AccessConfig{globalAccess, globalAccess}, + }, + { + name: "rule access overrides global access", + globalAccess: &globalAccess, + ruleAccess: &ruleAccess, + expectedHandlers: []int{1, 1}, + expectedAccess: []config.AccessConfig{ruleAccess, globalAccess}, + }, + { + name: "rule access applies only to its rule", + ruleAccess: &ruleAccess, + expectedHandlers: []int{1, 0}, + expectedAccess: []config.AccessConfig{ruleAccess, {}}, + }, + { + name: "no access adds no handlers", + expectedHandlers: []int{0, 0}, + expectedAccess: []config.AccessConfig{{}, {}}, + }, + { + name: "invalid global access returns an error", + globalAccess: &config.AccessConfig{ + Required: true, + AudTag: []string{"global-aud"}, + }, + expectedError: "access.TeamName cannot be blank", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + + conf := &config.Configuration{ + OriginRequest: config.OriginRequestConfig{Access: test.globalAccess}, + Ingress: []config.UnvalidatedIngressRule{ + { + Hostname: "example.com", + Service: "https://localhost:8000", + OriginRequest: config.OriginRequestConfig{ + Access: test.ruleAccess, + }, + }, + { + Service: "http_status:404", + }, + }, + } + + ing, err := ParseIngress(conf) + if test.expectedError != "" { + require.ErrorContains(t, err, test.expectedError) + return + } + require.NoError(t, err) + require.Len(t, ing.Rules, len(test.expectedHandlers)) + + for i, expectedHandlerCount := range test.expectedHandlers { + require.Len(t, ing.Rules[i].Handlers, expectedHandlerCount) + assert.Equal(t, test.expectedAccess[i], ing.Rules[i].Config.Access) + for _, handler := range ing.Rules[i].Handlers { + assert.Equal(t, "AccessJWTValidator", handler.Name()) + } + } + }) + } +} + func MustReadIngress(s string) *config.Configuration { var conf config.Configuration err := yaml.Unmarshal([]byte(s), &conf)