From f3f78a76e3f8343ef657d933eef55b77156b6c5a Mon Sep 17 00:00:00 2001 From: Johannes Koch Date: Tue, 29 Mar 2022 18:03:58 +0200 Subject: [PATCH 1/4] fix: only handle keys in certain attribute object values case-insensitively --- config/configload/schema.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/config/configload/schema.go b/config/configload/schema.go index e361c420e..57de9b3dd 100644 --- a/config/configload/schema.go +++ b/config/configload/schema.go @@ -264,13 +264,18 @@ func completeSchemaComponents(body hcl.Body, schema *hcl.BodySchema, attrs hcl.A continue } - keyName := strings.ToLower(seetie.ValueToString(k)) + keyName := seetie.ValueToString(k) + switch name { + case "add_request_headers", "add_response_headers", "beta_scope", "headers", "set_request_headers", "set_response_headers": + // header field names, method names: handle object keys case-insensitively + keyName = strings.ToLower(keyName) + } if _, ok := unique[keyName]; ok { errors = errors.Append(&hcl.Diagnostic{ Subject: &expr.SrcRange, Severity: hcl.DiagError, Summary: fmt.Sprintf("key in an attribute must be unique: '%s'", keyName), - Detail: "Key must be unique for " + string(keyName) + ".", + Detail: "Key must be unique for " + keyName + ".", }) } From 4a957d315fb084d12b3360ebcde4520171386dfc Mon Sep 17 00:00:00 2001 From: Johannes Koch Date: Tue, 29 Mar 2022 18:30:30 +0200 Subject: [PATCH 2/4] test for uniqueness check --- config/configload/validate_test.go | 219 +++++++++++++++++++++++++++++ 1 file changed, 219 insertions(+) diff --git a/config/configload/validate_test.go b/config/configload/validate_test.go index b4a1d95d2..ef0cd54a5 100644 --- a/config/configload/validate_test.go +++ b/config/configload/validate_test.go @@ -194,3 +194,222 @@ func TestLabels(t *testing.T) { }) } } + +func TestAttributeObjectKeys(t *testing.T) { + tests := []struct { + name string + hcl string + error string + }{ + { + "add_request_headers", + `server { + api { + endpoint "/a" { + add_request_headers = { + a = "a" + A = "A" + } + } + } +}`, + "couper.hcl:4,29-7,8: key in an attribute must be unique: 'a'; Key must be unique for a.", + }, + { + "add_response_headers", + `server { + api { + endpoint "/a" { + add_response_headers = { + a = "a" + A = "A" + } + } + } +}`, + "couper.hcl:4,30-7,8: key in an attribute must be unique: 'a'; Key must be unique for a.", + }, + { + "beta_scope", + `server { + api { + endpoint "/a" { + beta_scope = { + get = "a" + GeT = "A" + } + } + } +}`, + "couper.hcl:4,20-7,8: key in an attribute must be unique: 'get'; Key must be unique for get.", + }, + { + "headers", + `server { + api { + endpoint "/a" { + request { + headers = { + a = "a" + A = "A" + } + } + } + } +}`, + "couper.hcl:5,19-8,10: key in an attribute must be unique: 'a'; Key must be unique for a.", + }, + { + "set_request_headers", + `server { + api { + endpoint "/a" { + set_request_headers = { + a = "a" + A = "A" + } + } + } +}`, + "couper.hcl:4,29-7,8: key in an attribute must be unique: 'a'; Key must be unique for a.", + }, + { + "set_response_headers", + `server { + api { + endpoint "/a" { + set_response_headers = { + a = "a" + A = "A" + } + } + } +}`, + "couper.hcl:4,30-7,8: key in an attribute must be unique: 'a'; Key must be unique for a.", + }, + { + "json_body", + `server { + api { + endpoint "/a" { + request { + json_body = { + a = "a" + A = "A" + } + } + } + } +}`, + "", + }, + { + "form_body", + `server { + api { + endpoint "/a" { + request { + form_body = { + a = "a" + A = "A" + } + } + } + } +}`, + "", + }, + { + "beta_roles_map", + `server {} +definitions { + jwt "a" { + signature_algorithm = "HS256" + key = "asdf" + beta_roles_map = { + a = [] + A = [] + } + } +}`, + "", + }, + { + "beta_scope_map", + `server {} +definitions { + jwt "a" { + signature_algorithm = "HS256" + key = "asdf" + beta_scope_map = { + a = [] + A = [] + } + } +}`, + "", + }, + { + "claims", + `server {} +definitions { + jwt "a" { + signature_algorithm = "HS256" + key = "asdf" + claims = { + a = "a" + A = "A" + } + } +}`, + "", + }, + { + "custom_log_fields", + `server {} +definitions { + jwt "a" { + signature_algorithm = "HS256" + key = "asdf" + custom_log_fields = { + a = "a" + A = "A" + } + } +}`, + "", + }, + { + "environment_variables", + `server {} +defaults { + environment_variables = { + a = "a" + A = "A" + } +}`, + "", + }, + } + + logger, _ := logrustest.NewNullLogger() + log := logger.WithContext(context.TODO()) + + for _, tt := range tests { + t.Run(tt.name, func(subT *testing.T) { + conf, err := LoadBytes([]byte(tt.hcl), "couper.hcl") + if conf != nil { + _, err = runtime.NewServerConfiguration(conf, log, nil) + } + + var errMsg string + if err != nil { + errMsg = err.Error() + } + + if tt.error != errMsg { + subT.Errorf("%q: Unexpected configuration error:\n\tWant: %q\n\tGot: %q", tt.name, tt.error, errMsg) + } + }) + } +} From 4818bd191ae07dc9f27ea0d35f6953f5b7f86b1b Mon Sep 17 00:00:00 2001 From: Johannes Koch Date: Wed, 30 Mar 2022 09:26:26 +0200 Subject: [PATCH 3/4] changelog entry --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bf47dca0..6f39d1d15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ Unreleased changes are available as `avenga/couper:edge` container. * Couper [reads and merges configuration files](./docs/CLI.md#global-options) from a given directory ([#437](https://github.com/avenga/couper/pull/437)) * provided via `-d` command-line flag or `COUPER_FILE_DIRECTORY` environment variable +* **Fixed** + * Keys in object type attribute values are only handled case-insenstively if reasonable (e.g. the represent HTTP methods or header field values) ([#461](https://github.com/avenga/couper/pull/461)) + --- ## [1.8.0](https://github.com/avenga/couper/releases/tag/v1.8.0) From 4271b6d9ce53f3d439fde7eeca4496c511069bb6 Mon Sep 17 00:00:00 2001 From: Johannes Koch <53434855+johakoch@users.noreply.github.com> Date: Mon, 4 Apr 2022 11:39:03 +0200 Subject: [PATCH 4/4] Update CHANGELOG.md Co-authored-by: Joe Afflerbach --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f39d1d15..cb6657c41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ Unreleased changes are available as `avenga/couper:edge` container. * provided via `-d` command-line flag or `COUPER_FILE_DIRECTORY` environment variable * **Fixed** - * Keys in object type attribute values are only handled case-insenstively if reasonable (e.g. the represent HTTP methods or header field values) ([#461](https://github.com/avenga/couper/pull/461)) + * Keys in object type attribute values are only handled case-insensitively if reasonable (e.g. they represent HTTP methods or header field values) ([#461](https://github.com/avenga/couper/pull/461)) ---