Skip to content

Commit 3f1aa14

Browse files
aa1exzvlb
authored andcommitted
test: oauth2 http filter invalid params combination
Signed-off-by: Aleksandr Aleksandrov <aaleksandrov.cy@gmail.com>
1 parent 1dcc387 commit 3f1aa14

File tree

8 files changed

+101
-20
lines changed

8 files changed

+101
-20
lines changed

api/v1alpha1/httpfilter_webhook.go

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ package v1alpha1
1919
import (
2020
"context"
2121
"fmt"
22-
22+
oauth2v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/oauth2/v3"
2323
hcmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
2424
"github.com/kaasops/envoy-xds-controller/pkg/errors"
2525
"github.com/kaasops/envoy-xds-controller/pkg/options"
@@ -33,9 +33,9 @@ func (h *HttpFilter) Validate(ctx context.Context) error {
3333
}
3434

3535
for _, httpFilter := range h.Spec {
36-
httpFilterv3 := &hcmv3.HttpFilter{}
37-
if err := options.Unmarshaler.Unmarshal(httpFilter.Raw, httpFilterv3); err != nil {
38-
return errors.Wrap(err, errors.UnmarshalMessage)
36+
hf := &hcmv3.HttpFilter{}
37+
if err := UnmarshalAndValidateHTTPFilter(httpFilter.Raw, hf); err != nil {
38+
return err
3939
}
4040
}
4141

@@ -68,3 +68,36 @@ func (h *HttpFilter) ValidateDelete(ctx context.Context, cl client.Client) error
6868

6969
return nil
7070
}
71+
72+
func UnmarshalAndValidateHTTPFilter(raw []byte, httpFilter *hcmv3.HttpFilter) error {
73+
if err := options.Unmarshaler.Unmarshal(raw, httpFilter); err != nil {
74+
return errors.Wrap(err, errors.UnmarshalMessage)
75+
}
76+
if err := httpFilter.ValidateAll(); err != nil {
77+
return errors.WrapUKS(err, errors.InvalidHTTPFilter)
78+
}
79+
switch v := httpFilter.ConfigType.(type) {
80+
case *hcmv3.HttpFilter_TypedConfig:
81+
switch v.TypedConfig.TypeUrl {
82+
case "type.googleapis.com/envoy.extensions.filters.http.oauth2.v3.OAuth2":
83+
if err := validateOAuth2Filter(v); err != nil {
84+
return err
85+
}
86+
}
87+
}
88+
return nil
89+
}
90+
91+
func validateOAuth2Filter(v *hcmv3.HttpFilter_TypedConfig) error {
92+
var oauthCfg oauth2v3.OAuth2
93+
if err := v.TypedConfig.UnmarshalTo(&oauthCfg); err != nil {
94+
return errors.Wrap(err, errors.UnmarshalMessage)
95+
}
96+
if err := oauthCfg.ValidateAll(); err != nil {
97+
return errors.WrapUKS(err, errors.InvalidHTTPFilter)
98+
}
99+
if oauthCfg.Config.PreserveAuthorizationHeader && oauthCfg.Config.ForwardBearerToken {
100+
return errors.Newf("%s: preserve_authorization_header=true and forward_bearer_token=true", errors.InvalidParamsCombination)
101+
}
102+
return nil
103+
}

api/v1alpha1/virtualservice_webhook.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ func (vs *VirtualService) Validate(
7676
if vs.Spec.HTTPFilters != nil {
7777
for _, httpFilter := range vs.Spec.HTTPFilters {
7878
hf := &hcmv3.HttpFilter{}
79-
if err := options.Unmarshaler.Unmarshal(httpFilter.Raw, hf); err != nil {
80-
return errors.Wrap(err, errors.UnmarshalMessage)
79+
if err := UnmarshalAndValidateHTTPFilter(httpFilter.Raw, hf); err != nil {
80+
return err
8181
}
8282
}
8383
}
@@ -316,7 +316,7 @@ func validateAutoDiscovery(
316316
wildcardDomain := utils.GetWildcardDomain(domain)
317317
_, ok := index[wildcardDomain]
318318
if !ok {
319-
return errors.Newf("%s. Domain: %s", errors.DicoverNotFoundMessage, domain)
319+
return errors.Newf("%s. Domain: %s", errors.DiscoverNotFoundMessage, domain)
320320
}
321321
}
322322
}

pkg/errors/messages.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ var (
2929
AccessLogConfigDeleteUsedMessage = "cannot delete accesslogconfig, bc is used in Virtual Services: "
3030
HTTPFilterCannotBeEmptyMessage = "httpFilter could not be empty"
3131
HTTPFilterDeleteUsed = "cannot delete httpFilter, bc is used in Virtual Services: "
32+
InvalidHTTPFilter = "invalid http_filter"
33+
InvalidParamsCombination = "invalid combination of parameters"
3234
RouteCannotBeEmptyMessage = "route could not be empty"
3335
RouteDeleteUsed = "cannot delete route, bc is used in Virtual Services: "
3436
ClusterCannotBeEmptyMessage = "cluster could not be empty"
@@ -46,7 +48,7 @@ var (
4648
CertManaferCRDNotExistMessage = "cert Manager CRDs not exist. Perhaps Cert Manager is not installed in the Kubernetes cluster"
4749
TlsConfigManyParamMessage = "сannot be installed Issuer and ClusterIssuer in 1 config"
4850

49-
DicoverNotFoundMessage = "the secret with the certificate was not found for the domain"
51+
DiscoverNotFoundMessage = "the secret with the certificate was not found for the domain"
5052
CreateCertificateMessage = "cannot create certificate for domain"
5153
RegexDomainMessage = "regex domains not supported"
5254
)

pkg/factory/virtualservice/tls/tls.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ func (tf *TlsFactory) provideAutoDiscovery(ctx context.Context, domains []string
101101
wildcardDomain := utils.GetWildcardDomain(domain)
102102
secret, ok = tf.CertificatesIndex[wildcardDomain]
103103
if !ok {
104-
return CertificatesWithDomains, errors.NewUKS(fmt.Sprintf("domain - %v: %v", domain, errors.DicoverNotFoundMessage))
104+
return CertificatesWithDomains, errors.NewUKS(fmt.Sprintf("domain - %v: %v", domain, errors.DiscoverNotFoundMessage))
105105
}
106106
}
107107

pkg/factory/virtualservice/virtualservice.go

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -229,14 +229,9 @@ func (f *VirtualServiceFactory) HttpFilters(ctx context.Context, name string) ([
229229
httpFilters := []*hcmv3.HttpFilter{}
230230
for _, httpFilter := range f.Spec.HTTPFilters {
231231
hf := &hcmv3.HttpFilter{}
232-
if err := options.Unmarshaler.Unmarshal(httpFilter.Raw, hf); err != nil {
233-
return nil, errors.WrapUKS(err, errors.UnmarshalMessage)
232+
if err := v1alpha1.UnmarshalAndValidateHTTPFilter(httpFilter.Raw, hf); err != nil {
233+
return nil, err
234234
}
235-
236-
if err := hf.ValidateAll(); err != nil {
237-
return nil, errors.WrapUKS(err, errors.CannotValidateCacheResourceMessage)
238-
}
239-
240235
httpFilters = append(httpFilters, hf)
241236
}
242237

@@ -250,8 +245,8 @@ func (f *VirtualServiceFactory) HttpFilters(ctx context.Context, name string) ([
250245
}
251246
for _, httpFilter := range hfSpec.Spec {
252247
hf := &hcmv3.HttpFilter{}
253-
if err := options.Unmarshaler.Unmarshal(httpFilter.Raw, hf); err != nil {
254-
return nil, errors.WrapUKS(err, errors.UnmarshalMessage)
248+
if err := v1alpha1.UnmarshalAndValidateHTTPFilter(httpFilter.Raw, hf); err != nil {
249+
return nil, err
255250
}
256251
httpFilters = append(httpFilters, hf)
257252
}

test/conformance/tests/httpFilter.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ func init() {
1919
HttpFilter_CannotBeEmptyTest,
2020
HttpFilter_HasInvalidSpec,
2121
HttpFilter_DeleteUsed,
22+
HttpFilter_OAuth2InvalidParamsCombination,
2223
)
2324
}
2425

@@ -55,3 +56,11 @@ var HttpFilter_DeleteUsed = utils.TestCase{
5556
require.ErrorContains(t, err, fmt.Sprintf("%v%v%v", ValidationErrorMessage, errors.HTTPFilterDeleteUsed, []string{"virtual-service-used-hf"}))
5657
},
5758
}
59+
60+
var HttpFilter_OAuth2InvalidParamsCombination = utils.TestCase{
61+
ShortName: "HttpFilterOauth2InvalidParamsCombination",
62+
Description: "Test that the HttpFilter contains an invalid combination of parameters",
63+
Manifests: []string{"../testdata/conformance/httpfilter-oauth2-invalid-combination.yaml"},
64+
ApplyErrorContains: fmt.Sprintf("%v%v", ValidationErrorMessage, errors.InvalidParamsCombination),
65+
Test: func(t *testing.T, suite *utils.TestSuite) {},
66+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
apiVersion: envoy.kaasops.io/v1alpha1
2+
kind: HttpFilter
3+
metadata:
4+
name: invalid-combination
5+
spec:
6+
- name: envoy.filters.http.oauth2
7+
typed_config:
8+
"@type": type.googleapis.com/envoy.extensions.filters.http.oauth2.v3.OAuth2
9+
config:
10+
preserve_authorization_header: true
11+
token_endpoint:
12+
uri: "https://example.com/token"
13+
cluster: oauth2
14+
timeout: 10s
15+
authorization_endpoint: "https://example.com/auth"
16+
credentials:
17+
client_id: "example-id"
18+
token_secret:
19+
name: token
20+
sds_config:
21+
path: "./oauth2-token.yaml"
22+
hmac_secret:
23+
name: hmac
24+
sds_config:
25+
path: "./oauth2-hmac.yaml"
26+
redirect_uri: "https://%REQ(:authority)%/oauth/callback"
27+
redirect_path_matcher:
28+
path:
29+
exact: "/oauth/callback"
30+
signout_path:
31+
path:
32+
exact: "/oauth/signout"
33+
forward_bearer_token: true
34+
use_refresh_token: false
35+
auth_scopes:
36+
- "openid"
37+
- "profile"
38+
- "email"
39+
- "offline_access"

tools/make/tests.mk

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ e2e-1.29-1.30: envoy-1.30
4343
$(RUN_E2E)
4444
$(CLEANUP_ENVOY)
4545

46-
# E2E test on Kubernetes 1.30 for Envoy 1.31
46+
# E2E test on Kubernetes 1.29 for Envoy 1.31
4747
.PHONY: e2e-1.29-1.31
4848
e2e-1.29-1.31: envoy-1.31
4949
$(RUN_E2E)
@@ -53,7 +53,7 @@ e2e-1.29-1.31: envoy-1.31
5353
.PHONY: e2e-1.30
5454
e2e-1.30: prepare-kind kind-with-registry-1.30 build-deploy-exc e2e-1.30-1.30 e2e-1.30-1.31 cleanup-kind-with-registry
5555

56-
# E2E test on Kubernetes 1.29 for Envoy 1.30
56+
# E2E test on Kubernetes 1.30 for Envoy 1.30
5757
.PHONY: e2e-1.30-1.30
5858
e2e-1.30-1.30: envoy-1.30
5959
$(RUN_E2E)
@@ -72,3 +72,6 @@ endef
7272

7373
.PHONY: build-deploy-exc
7474
build-deploy-exc: image.build-local image.push-local kube-deploy-local
75+
76+
.PHONY: run-local
77+
run-local: prepare-kind kind-with-registry-1.30 build-deploy-exc

0 commit comments

Comments
 (0)