From 03cc0310ad465c08c93faf6a8d88c46c29e701dd Mon Sep 17 00:00:00 2001 From: Johannes Koch Date: Tue, 17 Jan 2023 09:06:18 +0100 Subject: [PATCH 01/14] beta_granted_permissions -> granted_permissions --- config/configload/validate_test.go | 30 ++++++++--------- .../content/2.configuration/5.variables.md | 2 +- .../2.configuration/9.access-control.md | 2 +- eval/context.go | 2 +- .../testdata/integration/config/03_couper.hcl | 8 ++--- .../testdata/integration/config/09_couper.hcl | 32 +++++++++---------- .../integration/endpoint_eval/20_couper.hcl | 2 +- 7 files changed, 39 insertions(+), 39 deletions(-) diff --git a/config/configload/validate_test.go b/config/configload/validate_test.go index 847eef82d..7b2cae723 100644 --- a/config/configload/validate_test.go +++ b/config/configload/validate_test.go @@ -472,13 +472,13 @@ func Test_validateBody(t *testing.T) { "couper.hcl:3,12-16: accessControl requires a label; ", }, { - "basic_auth reserved label beta_granted_permissions", + "basic_auth reserved label granted_permissions", `server {} definitions { - basic_auth "beta_granted_permissions" { + basic_auth "granted_permissions" { } }`, - "couper.hcl:3,18-44: accessControl uses reserved name as label; ", + "couper.hcl:3,18-39: accessControl uses reserved name as label; ", }, { "basic_auth reserved label beta_required_permission", @@ -490,13 +490,13 @@ func Test_validateBody(t *testing.T) { "couper.hcl:3,18-44: accessControl uses reserved name as label; ", }, { - "beta_oauth2 reserved label beta_granted_permissions", + "beta_oauth2 reserved label granted_permissions", `server {} definitions { - beta_oauth2 "beta_granted_permissions" { + beta_oauth2 "granted_permissions" { } }`, - "couper.hcl:3,19-45: accessControl uses reserved name as label; ", + "couper.hcl:3,19-40: accessControl uses reserved name as label; ", }, { "beta_oauth2 reserved label beta_required_permission", @@ -508,13 +508,13 @@ func Test_validateBody(t *testing.T) { "couper.hcl:3,19-45: accessControl uses reserved name as label; ", }, { - "jwt reserved label beta_granted_permissions", + "jwt reserved label granted_permissions", `server {} definitions { - jwt "beta_granted_permissions" { + jwt "granted_permissions" { } }`, - "couper.hcl:3,11-37: accessControl uses reserved name as label; ", + "couper.hcl:3,11-32: accessControl uses reserved name as label; ", }, { "jwt reserved label beta_required_permission", @@ -526,13 +526,13 @@ func Test_validateBody(t *testing.T) { "couper.hcl:3,11-37: accessControl uses reserved name as label; ", }, { - "oidc reserved label beta_granted_permissions", + "oidc reserved label granted_permissions", `server {} definitions { - oidc "beta_granted_permissions" { + oidc "granted_permissions" { } }`, - "couper.hcl:3,12-38: accessControl uses reserved name as label; ", + "couper.hcl:3,12-33: accessControl uses reserved name as label; ", }, { "oidc reserved label beta_required_permission", @@ -544,13 +544,13 @@ func Test_validateBody(t *testing.T) { "couper.hcl:3,12-38: accessControl uses reserved name as label; ", }, { - "saml reserved label beta_granted_permissions", + "saml reserved label granted_permissions", `server {} definitions { - saml "beta_granted_permissions" { + saml "granted_permissions" { } }`, - "couper.hcl:3,12-38: accessControl uses reserved name as label; ", + "couper.hcl:3,12-33: accessControl uses reserved name as label; ", }, { "saml reserved label beta_required_permission", diff --git a/docs/website/content/2.configuration/5.variables.md b/docs/website/content/2.configuration/5.variables.md index b644b3a9b..7fb9b2450 100644 --- a/docs/website/content/2.configuration/5.variables.md +++ b/docs/website/content/2.configuration/5.variables.md @@ -53,7 +53,7 @@ defaults { | `body` | string | Request message body | | | `form_body.` | list (string) | Parameter in a `application/x-www-form-urlencoded` body | | | `json_body` | various | Access JSON decoded message body. Media type must be `application/json` or `application/*+json`. | | -| `context.beta_granted_permissions` | list (string) | Permissions granted to the requester as yielded by access controls (see e.g. `beta_permissions_claim`, `beta_roles_claim` in the [`jwt` block](/configuration/block/jwt)). | `["perm1", "perm2"]` | +| `context.granted_permissions` | list (string) | Permissions granted to the requester as yielded by access controls (see e.g. `beta_permissions_claim`, `beta_roles_claim` in the [`jwt` block](/configuration/block/jwt)). | `["perm1", "perm2"]` | | `context.beta_required_permission` | string | Permission required to perform the requested operation (value of the `beta_required_permission` attribute of [`endpoint`](#endpoint-block) (or [`api`](/configuration/block/api)) block). | | | `context..` | various | Request context containing information from the [access control](/configuration/access-control). | | | `url` | string | Request URL | `"https://www.example.com/path/to?q=val&a=1"` | diff --git a/docs/website/content/2.configuration/9.access-control.md b/docs/website/content/2.configuration/9.access-control.md index c8525b184..6a45371f5 100644 --- a/docs/website/content/2.configuration/9.access-control.md +++ b/docs/website/content/2.configuration/9.access-control.md @@ -7,7 +7,7 @@ description: 'List of configurable access control layer blocks.' The configuration of access controls is twofold in Couper: You define the particular type such as `jwt` or `basic_auth` in [`definitions`](/configuration/block/definitions), each with a distinct label -(must not be one of the reserved names: `beta_granted_permissions`, `beta_required_permission`). +(must not be one of the reserved names: `granted_permissions`, `beta_required_permission`). Anywhere in the [`server` block](/configuration/block/server) those labels can be used in the `access_control` list to protect the respective block. diff --git a/eval/context.go b/eval/context.go index d310ac9c8..1e326ac92 100644 --- a/eval/context.go +++ b/eval/context.go @@ -554,7 +554,7 @@ func NewRawOrigin(u *url.URL) *url.URL { } const ( - betaGrantedPermissions = "beta_granted_permissions" + betaGrantedPermissions = "granted_permissions" betaRequiredPermission = "beta_required_permission" ) diff --git a/server/testdata/integration/config/03_couper.hcl b/server/testdata/integration/config/03_couper.hcl index e4208bbd1..8a1b9ad7c 100644 --- a/server/testdata/integration/config/03_couper.hcl +++ b/server/testdata/integration/config/03_couper.hcl @@ -108,7 +108,7 @@ server "acs" { response { headers = { x-jwt-sub = request.context.JWTToken.sub - x-granted-permissions = json_encode(request.context.beta_granted_permissions) + x-granted-permissions = json_encode(request.context.granted_permissions) } } } @@ -119,7 +119,7 @@ server "acs" { response { headers = { x-jwt-sub = request.context.JWT_token_value_query.sub - x-granted-permissions = json_encode(request.context.beta_granted_permissions) + x-granted-permissions = json_encode(request.context.granted_permissions) } } } @@ -130,7 +130,7 @@ server "acs" { response { headers = { x-jwt-sub = request.context.JWT_token_value_body.sub - x-granted-permissions = json_encode(request.context.beta_granted_permissions) + x-granted-permissions = json_encode(request.context.granted_permissions) } } } @@ -231,7 +231,7 @@ server "acs" { response { headers = { x-jwt-sub = request.context.JWKS_scope.sub - x-granted-permissions = json_encode(request.context.beta_granted_permissions) + x-granted-permissions = json_encode(request.context.granted_permissions) } } } diff --git a/server/testdata/integration/config/09_couper.hcl b/server/testdata/integration/config/09_couper.hcl index 96fbde624..87f1fad1c 100644 --- a/server/testdata/integration/config/09_couper.hcl +++ b/server/testdata/integration/config/09_couper.hcl @@ -11,7 +11,7 @@ server "scoped jwt" { response { status = 204 headers = { - x-granted-permissions = json_encode(request.context.beta_granted_permissions) + x-granted-permissions = json_encode(request.context.granted_permissions) } } } @@ -31,7 +31,7 @@ server "scoped jwt" { response { status = 204 headers = { - x-granted-permissions = json_encode(request.context.beta_granted_permissions) + x-granted-permissions = json_encode(request.context.granted_permissions) } } } @@ -40,7 +40,7 @@ server "scoped jwt" { response { status = 204 headers = { - x-granted-permissions = json_encode(request.context.beta_granted_permissions) + x-granted-permissions = json_encode(request.context.granted_permissions) } } } @@ -51,7 +51,7 @@ server "scoped jwt" { response { status = 204 headers = { - x-granted-permissions = json_encode(request.context.beta_granted_permissions) + x-granted-permissions = json_encode(request.context.granted_permissions) } } } @@ -60,7 +60,7 @@ server "scoped jwt" { response { status = 204 headers = { - x-granted-permissions = json_encode(request.context.beta_granted_permissions) + x-granted-permissions = json_encode(request.context.granted_permissions) } } } @@ -69,7 +69,7 @@ server "scoped jwt" { response { status = 204 headers = { - x-granted-permissions = json_encode(request.context.beta_granted_permissions) + x-granted-permissions = json_encode(request.context.granted_permissions) } } } @@ -78,7 +78,7 @@ server "scoped jwt" { response { status = 204 headers = { - x-granted-permissions = json_encode(request.context.beta_granted_permissions) + x-granted-permissions = json_encode(request.context.granted_permissions) } } } @@ -87,7 +87,7 @@ server "scoped jwt" { response { status = 204 headers = { - x-granted-permissions = json_encode(request.context.beta_granted_permissions) + x-granted-permissions = json_encode(request.context.granted_permissions) } } } @@ -96,7 +96,7 @@ server "scoped jwt" { response { status = 204 headers = { - x-granted-permissions = json_encode(request.context.beta_granted_permissions) + x-granted-permissions = json_encode(request.context.granted_permissions) } } } @@ -104,7 +104,7 @@ server "scoped jwt" { response { status = 204 headers = { - x-granted-permissions = json_encode(request.context.beta_granted_permissions) + x-granted-permissions = json_encode(request.context.granted_permissions) } } } @@ -121,7 +121,7 @@ server "scoped jwt" { response { status = 204 headers = { - x-granted-permissions = json_encode(request.context.beta_granted_permissions) + x-granted-permissions = json_encode(request.context.granted_permissions) } } } @@ -141,7 +141,7 @@ server "scoped jwt" { response { status = 204 headers = { - x-granted-permissions = json_encode(request.context.beta_granted_permissions) + x-granted-permissions = json_encode(request.context.granted_permissions) } } } @@ -154,7 +154,7 @@ server "scoped jwt" { response { status = 204 headers = { - x-granted-permissions = json_encode(request.context.beta_granted_permissions) + x-granted-permissions = json_encode(request.context.granted_permissions) } } } @@ -163,7 +163,7 @@ server "scoped jwt" { response { status = 204 headers = { - x-granted-permissions = json_encode(request.context.beta_granted_permissions) + x-granted-permissions = json_encode(request.context.granted_permissions) } } } @@ -176,7 +176,7 @@ server "scoped jwt" { response { status = 204 headers = { - x-granted-permissions = json_encode(request.context.beta_granted_permissions) + x-granted-permissions = json_encode(request.context.granted_permissions) } } } @@ -185,7 +185,7 @@ server "scoped jwt" { response { status = 204 headers = { - x-granted-permissions = json_encode(request.context.beta_granted_permissions) + x-granted-permissions = json_encode(request.context.granted_permissions) } } } diff --git a/server/testdata/integration/endpoint_eval/20_couper.hcl b/server/testdata/integration/endpoint_eval/20_couper.hcl index abf6a3482..7fd878c36 100644 --- a/server/testdata/integration/endpoint_eval/20_couper.hcl +++ b/server/testdata/integration/endpoint_eval/20_couper.hcl @@ -181,7 +181,7 @@ server "cty.NilVal" { headers = { X-Value = json_encode(merge({ "obj": {"key": "val"} }, { foo = "bar" - xxxx = request.context.beta_granted_permissions + xxxx = request.context.granted_permissions })) Z-Value = "y" } From 622a12ac12bbd0f4cd621544da0f687ec869e295 Mon Sep 17 00:00:00 2001 From: Johannes Koch Date: Tue, 17 Jan 2023 09:27:39 +0100 Subject: [PATCH 02/14] betaGrantedPermissions -> grantedPermissions --- eval/context.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/eval/context.go b/eval/context.go index 1e326ac92..ce52702b0 100644 --- a/eval/context.go +++ b/eval/context.go @@ -554,13 +554,13 @@ func NewRawOrigin(u *url.URL) *url.URL { } const ( - betaGrantedPermissions = "granted_permissions" + grantedPermissions = "granted_permissions" betaRequiredPermission = "beta_required_permission" ) func IsReservedContextName(name string) bool { switch name { - case betaGrantedPermissions, betaRequiredPermission: + case grantedPermissions, betaRequiredPermission: return true } @@ -577,9 +577,9 @@ func newVariable(ctx context.Context, cookies []*http.Cookie, headers http.Heade } ctxAcMap[name] = seetie.MapToValue(dataMap) } - grantedPermissions, _ := ctx.Value(request.BetaGrantedPermissions).([]string) - if len(grantedPermissions) > 0 { - ctxAcMap[betaGrantedPermissions] = seetie.GoToValue(grantedPermissions) + gp, _ := ctx.Value(request.BetaGrantedPermissions).([]string) + if len(gp) > 0 { + ctxAcMap[grantedPermissions] = seetie.GoToValue(gp) } if requiredPermission, permissionSet := ctx.Value(request.BetaRequiredPermission).(string); permissionSet { ctxAcMap[betaRequiredPermission] = seetie.GoToValue(requiredPermission) From ce281055ab13a711242a8db863dacc1deaf8163d Mon Sep 17 00:00:00 2001 From: Johannes Koch Date: Tue, 17 Jan 2023 09:36:50 +0100 Subject: [PATCH 03/14] request.BetaGrantedPermissions -> request.GrantedPermissions --- accesscontrol/jwt.go | 4 ++-- accesscontrol/jwt_test.go | 2 +- accesscontrol/permissions.go | 2 +- accesscontrol/permissions_test.go | 2 +- config/request/context_key.go | 2 +- eval/context.go | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/accesscontrol/jwt.go b/accesscontrol/jwt.go index e40265a2f..49d8354ca 100644 --- a/accesscontrol/jwt.go +++ b/accesscontrol/jwt.go @@ -257,11 +257,11 @@ func (j *JWT) Validate(req *http.Request) error { log := req.Context().Value(request.LogEntry).(*logrus.Entry).WithContext(req.Context()) jwtGrantedPermissions := j.getGrantedPermissions(tokenClaims, log) - grantedPermissions, _ := ctx.Value(request.BetaGrantedPermissions).([]string) + grantedPermissions, _ := ctx.Value(request.GrantedPermissions).([]string) grantedPermissions = append(grantedPermissions, jwtGrantedPermissions...) - ctx = context.WithValue(ctx, request.BetaGrantedPermissions, grantedPermissions) + ctx = context.WithValue(ctx, request.GrantedPermissions, grantedPermissions) *req = *req.WithContext(ctx) diff --git a/accesscontrol/jwt_test.go b/accesscontrol/jwt_test.go index c4d563b2c..9ca387061 100644 --- a/accesscontrol/jwt_test.go +++ b/accesscontrol/jwt_test.go @@ -634,7 +634,7 @@ func Test_JWT_yields_permissions(t *testing.T) { return } - grantedPermissionsList, ok := req.Context().Value(request.BetaGrantedPermissions).([]string) + grantedPermissionsList, ok := req.Context().Value(request.GrantedPermissions).([]string) if !ok { subT.Errorf("Expected granted permissions within request context") } else { diff --git a/accesscontrol/permissions.go b/accesscontrol/permissions.go index 40cd6c004..d71c81b65 100644 --- a/accesscontrol/permissions.go +++ b/accesscontrol/permissions.go @@ -99,7 +99,7 @@ func (p *PermissionsControl) Validate(req *http.Request) error { evalCtx := eval.ContextFromRequest(req) *req = *req.WithContext(evalCtx.WithClientRequest(req)) - grantedPermission, ok := ctx.Value(request.BetaGrantedPermissions).([]string) + grantedPermission, ok := ctx.Value(request.GrantedPermissions).([]string) if !ok { return errors.BetaInsufficientPermissions.Messagef("no permissions granted") } diff --git a/accesscontrol/permissions_test.go b/accesscontrol/permissions_test.go index d6bfe6ae4..7ae139e89 100644 --- a/accesscontrol/permissions_test.go +++ b/accesscontrol/permissions_test.go @@ -256,7 +256,7 @@ func Test_PermissionsControl(t *testing.T) { req := httptest.NewRequest(tt.method, "/", nil) if tt.grantedPermissions != nil { ctx := req.Context() - ctx = context.WithValue(ctx, request.BetaGrantedPermissions, tt.grantedPermissions) + ctx = context.WithValue(ctx, request.GrantedPermissions, tt.grantedPermissions) *req = *req.WithContext(ctx) } err := pc.Validate(req) diff --git a/config/request/context_key.go b/config/request/context_key.go index a5b2023a5..912d8be54 100644 --- a/config/request/context_key.go +++ b/config/request/context_key.go @@ -9,7 +9,6 @@ const ( BackendBytes BackendName BackendParams - BetaGrantedPermissions BetaRequiredPermission BufferOptions ConfigDryRun @@ -20,6 +19,7 @@ const ( EndpointKind EndpointSequenceDependsOn Error + GrantedPermissions Handler LogCustomAccess LogCustomUpstreamValue diff --git a/eval/context.go b/eval/context.go index ce52702b0..c6168c0ef 100644 --- a/eval/context.go +++ b/eval/context.go @@ -577,7 +577,7 @@ func newVariable(ctx context.Context, cookies []*http.Cookie, headers http.Heade } ctxAcMap[name] = seetie.MapToValue(dataMap) } - gp, _ := ctx.Value(request.BetaGrantedPermissions).([]string) + gp, _ := ctx.Value(request.GrantedPermissions).([]string) if len(gp) > 0 { ctxAcMap[grantedPermissions] = seetie.GoToValue(gp) } From 27669e430f81c0ba1436353e28acdc3c9588ffc4 Mon Sep 17 00:00:00 2001 From: Johannes Koch Date: Tue, 17 Jan 2023 10:08:02 +0100 Subject: [PATCH 04/14] beta_required_permission -> required_permission --- accesscontrol/permissions.go | 2 +- accesscontrol/permissions_test.go | 8 +-- config/api.go | 2 +- config/configload/endpoint.go | 2 +- config/configload/load.go | 2 +- config/configload/schema.go | 2 +- config/configload/validate_test.go | 50 +++++++++---------- config/endpoint.go | 2 +- .../content/2.configuration/4.block/api.md | 20 ++++---- .../2.configuration/4.block/endpoint.md | 22 ++++---- .../content/2.configuration/5.variables.md | 2 +- .../2.configuration/9.access-control.md | 2 +- eval/context.go | 2 +- internal/seetie/convert.go | 4 +- server/http_integration_test.go | 4 +- .../testdata/integration/config/09_couper.hcl | 38 +++++++------- .../testdata/integration/config/11_couper.hcl | 8 +-- .../integration/error_handler/04_couper.hcl | 10 ++-- .../testdata/integration/logs/01_couper.hcl | 2 +- .../testdata/multi/server/couper.d/couper.hcl | 2 +- 20 files changed, 93 insertions(+), 93 deletions(-) diff --git a/accesscontrol/permissions.go b/accesscontrol/permissions.go index d71c81b65..274b71508 100644 --- a/accesscontrol/permissions.go +++ b/accesscontrol/permissions.go @@ -51,7 +51,7 @@ func (r *requiredPermissions) getPermission(method string) (string, error) { permission, exists := r.permissions[method] if !exists { - return "", errors.MethodNotAllowed.Messagef("method %s not allowed by beta_required_permission", method) + return "", errors.MethodNotAllowed.Messagef("method %s not allowed by required_permission", method) } return permission, nil } diff --git a/accesscontrol/permissions_test.go b/accesscontrol/permissions_test.go index 7ae139e89..9305d3e82 100644 --- a/accesscontrol/permissions_test.go +++ b/accesscontrol/permissions_test.go @@ -112,7 +112,7 @@ func Test_PermissionsControl(t *testing.T) { map[string]string{}, http.MethodGet, nil, - "method not allowed error: method GET not allowed by beta_required_permission", + "method not allowed error: method GET not allowed by required_permission", }, { "no method permitted, permission granted", @@ -120,7 +120,7 @@ func Test_PermissionsControl(t *testing.T) { map[string]string{}, http.MethodPost, []string{"read"}, - "method not allowed error: method POST not allowed by beta_required_permission", + "method not allowed error: method POST not allowed by required_permission", }, { "method permitted, no permission required, no permission granted", @@ -184,7 +184,7 @@ func Test_PermissionsControl(t *testing.T) { map[string]string{"*": "read"}, "BREW", []string{"read"}, - "method not allowed error: method BREW not allowed by beta_required_permission", + "method not allowed error: method BREW not allowed by required_permission", }, { "standard method not allowed", @@ -192,7 +192,7 @@ func Test_PermissionsControl(t *testing.T) { map[string]string{http.MethodGet: ""}, http.MethodPost, nil, - "method not allowed error: method POST not allowed by beta_required_permission", + "method not allowed error: method POST not allowed by required_permission", }, { "method permitted, permission required, no permissions granted", diff --git a/config/api.go b/config/api.go index ddec6ca22..7fff6ba0d 100644 --- a/config/api.go +++ b/config/api.go @@ -44,7 +44,7 @@ func (a API) Inline() interface{} { type Inline struct { meta.ResponseHeadersAttributes meta.LogFieldsAttribute - RequiredPermission hcl.Expression `hcl:"beta_required_permission,optional" docs:"Permission required to use this API (see [error type](/configuration/error-handling#error-types) {beta_insufficient_permissions})." type:"string or object (string)"` + RequiredPermission hcl.Expression `hcl:"required_permission,optional" docs:"Permission required to use this API (see [error type](/configuration/error-handling#error-types) {beta_insufficient_permissions})." type:"string or object (string)"` } return &Inline{} diff --git a/config/configload/endpoint.go b/config/configload/endpoint.go index 5e9cf9b5d..9aa035ea7 100644 --- a/config/configload/endpoint.go +++ b/config/configload/endpoint.go @@ -44,7 +44,7 @@ func refineEndpoints(helper *helper, endpoints config.Endpoints, checkPathPatter } } - rp := endpointBody.Attributes["beta_required_permission"] + rp := endpointBody.Attributes["required_permission"] if rp != nil { ep.RequiredPermission = rp.Expr } diff --git a/config/configload/load.go b/config/configload/load.go index 59ab42c40..2f76b40e8 100644 --- a/config/configload/load.go +++ b/config/configload/load.go @@ -427,7 +427,7 @@ func LoadConfig(body *hclsyntax.Body) (*config.Couper, error) { return nil, err } - rp := apiBody.Attributes["beta_required_permission"] + rp := apiBody.Attributes["required_permission"] if rp != nil { apiConfig.RequiredPermission = rp.Expr } diff --git a/config/configload/schema.go b/config/configload/schema.go index ec24d3df9..c754c980a 100644 --- a/config/configload/schema.go +++ b/config/configload/schema.go @@ -214,7 +214,7 @@ func completeSchemaComponents(body hcl.Body, schema *hcl.BodySchema, keyName := seetie.ValueToString(k) switch name { - case "add_request_headers", "add_response_headers", "beta_required_permission", "headers", "set_request_headers", "set_response_headers": + case "add_request_headers", "add_response_headers", "required_permission", "headers", "set_request_headers", "set_response_headers": // header field names, method names: handle object keys case-insensitively keyName = strings.ToLower(keyName) } diff --git a/config/configload/validate_test.go b/config/configload/validate_test.go index 7b2cae723..795c7a101 100644 --- a/config/configload/validate_test.go +++ b/config/configload/validate_test.go @@ -481,13 +481,13 @@ func Test_validateBody(t *testing.T) { "couper.hcl:3,18-39: accessControl uses reserved name as label; ", }, { - "basic_auth reserved label beta_required_permission", + "basic_auth reserved label required_permission", `server {} definitions { - basic_auth "beta_required_permission" { + basic_auth "required_permission" { } }`, - "couper.hcl:3,18-44: accessControl uses reserved name as label; ", + "couper.hcl:3,18-39: accessControl uses reserved name as label; ", }, { "beta_oauth2 reserved label granted_permissions", @@ -499,13 +499,13 @@ func Test_validateBody(t *testing.T) { "couper.hcl:3,19-40: accessControl uses reserved name as label; ", }, { - "beta_oauth2 reserved label beta_required_permission", + "beta_oauth2 reserved label required_permission", `server {} definitions { - beta_oauth2 "beta_required_permission" { + beta_oauth2 "required_permission" { } }`, - "couper.hcl:3,19-45: accessControl uses reserved name as label; ", + "couper.hcl:3,19-40: accessControl uses reserved name as label; ", }, { "jwt reserved label granted_permissions", @@ -517,13 +517,13 @@ func Test_validateBody(t *testing.T) { "couper.hcl:3,11-32: accessControl uses reserved name as label; ", }, { - "jwt reserved label beta_required_permission", + "jwt reserved label required_permission", `server {} definitions { - jwt "beta_required_permission" { + jwt "required_permission" { } }`, - "couper.hcl:3,11-37: accessControl uses reserved name as label; ", + "couper.hcl:3,11-32: accessControl uses reserved name as label; ", }, { "oidc reserved label granted_permissions", @@ -535,13 +535,13 @@ func Test_validateBody(t *testing.T) { "couper.hcl:3,12-33: accessControl uses reserved name as label; ", }, { - "oidc reserved label beta_required_permission", + "oidc reserved label required_permission", `server {} definitions { - oidc "beta_required_permission" { + oidc "required_permission" { } }`, - "couper.hcl:3,12-38: accessControl uses reserved name as label; ", + "couper.hcl:3,12-33: accessControl uses reserved name as label; ", }, { "saml reserved label granted_permissions", @@ -553,13 +553,13 @@ func Test_validateBody(t *testing.T) { "couper.hcl:3,12-33: accessControl uses reserved name as label; ", }, { - "saml reserved label beta_required_permission", + "saml reserved label required_permission", `server {} definitions { - saml "beta_required_permission" { + saml "required_permission" { } }`, - "couper.hcl:3,12-38: accessControl uses reserved name as label; ", + "couper.hcl:3,12-33: accessControl uses reserved name as label; ", }, { "duplicate AC labels 1", @@ -1163,18 +1163,18 @@ func TestAttributeObjectKeys(t *testing.T) { "couper.hcl:4,30-7,8: key in an attribute must be unique: 'a'; Key must be unique for a.", }, { - "beta_required_permission", + "required_permission", `server { api { endpoint "/a" { - beta_required_permission = { + required_permission = { get = "a" GeT = "A" } } } }`, - "couper.hcl:4,34-7,8: key in an attribute must be unique: 'get'; Key must be unique for get.", + "couper.hcl:4,29-7,8: key in an attribute must be unique: 'get'; Key must be unique for get.", }, { "headers", @@ -1352,7 +1352,7 @@ func TestPermissionMixed(t *testing.T) { `server { api "foo" { endpoint "/a" { - beta_required_permission = "a" + required_permission = "a" response {} } endpoint "/b" { @@ -1367,11 +1367,11 @@ func TestPermissionMixed(t *testing.T) { `server { api "foo" { endpoint "/a" { - beta_required_permission = "a" + required_permission = "a" response {} } endpoint "/b" { - beta_required_permission = "" + required_permission = "" response {} } } @@ -1382,9 +1382,9 @@ func TestPermissionMixed(t *testing.T) { "no mix: permission set by api", `server { api "foo" { - beta_required_permission = "api" + required_permission = "api" endpoint "/a" { - beta_required_permission = "a" + required_permission = "a" response {} } endpoint "/b" { @@ -1399,7 +1399,7 @@ func TestPermissionMixed(t *testing.T) { `server { api "foo" { endpoint "/a" { - beta_required_permission = "a" + required_permission = "a" response {} } endpoint "/b" { @@ -1420,7 +1420,7 @@ definitions { `server { api "foo" { endpoint "/a" { - beta_required_permission = "a" + required_permission = "a" response {} } } diff --git a/config/endpoint.go b/config/endpoint.go index 477fc7c96..289b87345 100644 --- a/config/endpoint.go +++ b/config/endpoint.go @@ -51,7 +51,7 @@ func (e Endpoint) Inline() interface{} { meta.QueryParamsAttributes meta.LogFieldsAttribute ResponseStatus *uint8 `hcl:"set_response_status,optional" docs:"Modifies the response status code."` - RequiredPermission hcl.Expression `hcl:"beta_required_permission,optional" docs:"Permission required to use this endpoint (see [error type](/configuration/error-handling#error-types) {beta_insufficient_permissions})." type:"string or object (string)"` + RequiredPermission hcl.Expression `hcl:"required_permission,optional" docs:"Permission required to use this endpoint (see [error type](/configuration/error-handling#error-types) {beta_insufficient_permissions})." type:"string or object (string)"` } return &Inline{} diff --git a/docs/website/content/2.configuration/4.block/api.md b/docs/website/content/2.configuration/4.block/api.md index 6977c2bf3..9fcda96b7 100644 --- a/docs/website/content/2.configuration/4.block/api.md +++ b/docs/website/content/2.configuration/4.block/api.md @@ -17,18 +17,18 @@ The default value `*` can be combined with additional methods. Methods are match **Example:** `allowed_methods = ["GET", "POST"]` or `allowed_methods = ["*", "BREW"]` -### Attribute `beta_required_permission` +### Attribute `required_permission` If the value is a string, the same permission applies to all request methods. If there are different permissions for different request methods, use an object with the request methods as keys and string values. Methods not specified in this object are not permitted. `"*"` is the key for "all other standard methods". Methods other than `GET`, `HEAD`, `POST`, `PUT`, `PATCH`, `DELETE`, `OPTIONS` must be specified explicitly. A value `""` means "no permission required". **Example:** ```hcl -beta_required_permission = "read" +required_permission = "read" # or -beta_required_permission = { post = "write", "*" = "" } +required_permission = { post = "write", "*" = "" } # or -beta_required_permission = default(request.path_params.p, "not_set") +required_permission = default(request.path_params.p, "not_set") ``` ::attributes @@ -58,12 +58,6 @@ values: [ "name": "base_path", "type": "string" }, - { - "default": "", - "description": "Permission required to use this API (see [error type](/configuration/error-handling#error-types) `beta_insufficient_permissions`).", - "name": "beta_required_permission", - "type": "string or object (string)" - }, { "default": "", "description": "log fields for [custom logging](/observation/logging#custom-logging). Inherited by nested blocks.", @@ -88,6 +82,12 @@ values: [ "name": "remove_response_headers", "type": "tuple (string)" }, + { + "default": "", + "description": "Permission required to use this API (see [error type](/configuration/error-handling#error-types) `beta_insufficient_permissions`).", + "name": "required_permission", + "type": "string or object (string)" + }, { "default": "", "description": "key/value pairs to set as response headers in the client response", diff --git a/docs/website/content/2.configuration/4.block/endpoint.md b/docs/website/content/2.configuration/4.block/endpoint.md index b2c72ea84..4f4de0248 100644 --- a/docs/website/content/2.configuration/4.block/endpoint.md +++ b/docs/website/content/2.configuration/4.block/endpoint.md @@ -23,18 +23,18 @@ The default value `"*"` can be combined with additional methods. Methods are mat allowed_methods = ["GET", "POST"]` or `allowed_methods = ["*", "BREW"] ``` -### Attribute `beta_required_permission` +### Attribute `required_permission` -Overrides `beta_required_permission` in a containing `api` block. If the value is a string, the same permission applies to all request methods. If there are different permissions for different request methods, use an object with the request methods as keys and string values. Methods not specified in this object are not permitted. `"*"` is the key for "all other standard methods". Methods other than `GET`, `HEAD`, `POST`, `PUT`, `PATCH`, `DELETE`, `OPTIONS` must be specified explicitly. A value `""` means "no permission required". For `api` blocks with at least two `endpoint`s, all endpoints must have either a) no `beta_required_permission` set or b) either `beta_required_permission` or `disable_access_control` set. Otherwise, a configuration error is thrown. +Overrides `required_permission` in a containing `api` block. If the value is a string, the same permission applies to all request methods. If there are different permissions for different request methods, use an object with the request methods as keys and string values. Methods not specified in this object are not permitted. `"*"` is the key for "all other standard methods". Methods other than `GET`, `HEAD`, `POST`, `PUT`, `PATCH`, `DELETE`, `OPTIONS` must be specified explicitly. A value `""` means "no permission required". For `api` blocks with at least two `endpoint`s, all endpoints must have either a) no `required_permission` set or b) either `required_permission` or `disable_access_control` set. Otherwise, a configuration error is thrown. **Example:** ```hcl -beta_required_permission = "read" +required_permission = "read" # or -beta_required_permission = { post = "write", "*" = "" } +required_permission = { post = "write", "*" = "" } # or -beta_required_permission = default(request.path_params.p, "not_set") +required_permission = default(request.path_params.p, "not_set") ``` ::attributes @@ -76,12 +76,6 @@ values: [ "name": "allowed_methods", "type": "tuple (string)" }, - { - "default": "", - "description": "Permission required to use this endpoint (see [error type](/configuration/error-handling#error-types) `beta_insufficient_permissions`).", - "name": "beta_required_permission", - "type": "string or object (string)" - }, { "default": "", "description": "log fields for [custom logging](/observation/logging#custom-logging). Inherited by nested blocks.", @@ -136,6 +130,12 @@ values: [ "name": "request_body_limit", "type": "string" }, + { + "default": "", + "description": "Permission required to use this endpoint (see [error type](/configuration/error-handling#error-types) `beta_insufficient_permissions`).", + "name": "required_permission", + "type": "string or object (string)" + }, { "default": "", "description": "key/value pairs to set query parameters in the upstream request URL", diff --git a/docs/website/content/2.configuration/5.variables.md b/docs/website/content/2.configuration/5.variables.md index 7fb9b2450..6bf85d570 100644 --- a/docs/website/content/2.configuration/5.variables.md +++ b/docs/website/content/2.configuration/5.variables.md @@ -54,7 +54,7 @@ defaults { | `form_body.` | list (string) | Parameter in a `application/x-www-form-urlencoded` body | | | `json_body` | various | Access JSON decoded message body. Media type must be `application/json` or `application/*+json`. | | | `context.granted_permissions` | list (string) | Permissions granted to the requester as yielded by access controls (see e.g. `beta_permissions_claim`, `beta_roles_claim` in the [`jwt` block](/configuration/block/jwt)). | `["perm1", "perm2"]` | -| `context.beta_required_permission` | string | Permission required to perform the requested operation (value of the `beta_required_permission` attribute of [`endpoint`](#endpoint-block) (or [`api`](/configuration/block/api)) block). | | +| `context.required_permission` | string | Permission required to perform the requested operation (value of the `required_permission` attribute of [`endpoint`](#endpoint-block) (or [`api`](/configuration/block/api)) block). | | | `context..` | various | Request context containing information from the [access control](/configuration/access-control). | | | `url` | string | Request URL | `"https://www.example.com/path/to?q=val&a=1"` | | `origin` | string | Origin of the request URL | `"https://www.example.com"` | diff --git a/docs/website/content/2.configuration/9.access-control.md b/docs/website/content/2.configuration/9.access-control.md index 6a45371f5..aa995df17 100644 --- a/docs/website/content/2.configuration/9.access-control.md +++ b/docs/website/content/2.configuration/9.access-control.md @@ -7,7 +7,7 @@ description: 'List of configurable access control layer blocks.' The configuration of access controls is twofold in Couper: You define the particular type such as `jwt` or `basic_auth` in [`definitions`](/configuration/block/definitions), each with a distinct label -(must not be one of the reserved names: `granted_permissions`, `beta_required_permission`). +(must not be one of the reserved names: `granted_permissions`, `required_permission`). Anywhere in the [`server` block](/configuration/block/server) those labels can be used in the `access_control` list to protect the respective block. diff --git a/eval/context.go b/eval/context.go index c6168c0ef..b68941dd7 100644 --- a/eval/context.go +++ b/eval/context.go @@ -555,7 +555,7 @@ func NewRawOrigin(u *url.URL) *url.URL { const ( grantedPermissions = "granted_permissions" - betaRequiredPermission = "beta_required_permission" + betaRequiredPermission = "required_permission" ) func IsReservedContextName(name string) bool { diff --git a/internal/seetie/convert.go b/internal/seetie/convert.go index 7af31c793..f75a93830 100644 --- a/internal/seetie/convert.go +++ b/internal/seetie/convert.go @@ -71,14 +71,14 @@ func ValueToPermission(val cty.Value) (string, map[string]string, error) { permissionMap := make(map[string]string) for k, v := range val.AsValueMap() { if v.Type() != cty.String { - return "", nil, fmt.Errorf("unsupported value for method %q in beta_required_permission", k) + return "", nil, fmt.Errorf("unsupported value for method %q in required_permission", k) } permissionMap[strings.ToUpper(k)] = v.AsString() } return "", permissionMap, nil } } - return "", nil, fmt.Errorf("unsupported value for beta_required_permission") + return "", nil, fmt.Errorf("unsupported value for required_permission") } func ValuesMapToValue(m url.Values) cty.Value { diff --git a/server/http_integration_test.go b/server/http_integration_test.go index 140cf3247..eab92d0fa 100644 --- a/server/http_integration_test.go +++ b/server/http_integration_test.go @@ -3767,7 +3767,7 @@ func Test_Permissions(t *testing.T) { {"by scope: unauthorized", http.MethodGet, "/scope/foo", false, http.StatusUnauthorized, ``, ``, "access control error: scoped_jwt: token required", "jwt_token_missing"}, {"by scope: no permission required by endpoint", http.MethodGet, "/scope/foo", true, http.StatusNoContent, `["a"]`, ``, "", ""}, {"by scope: permission required by endpoint: insufficient permissions", http.MethodPost, "/scope/foo", true, http.StatusForbidden, ``, ``, `access control error: required permission "foo" not granted`, "beta_insufficient_permissions"}, - {"by scope: method not permitted", http.MethodDelete, "/scope/foo", true, http.StatusMethodNotAllowed, ``, ``, "method not allowed error: method DELETE not allowed by beta_required_permission", ""}, + {"by scope: method not permitted", http.MethodDelete, "/scope/foo", true, http.StatusMethodNotAllowed, ``, ``, "method not allowed error: method DELETE not allowed by required_permission", ""}, {"by scope: permission required by endpoint via *: insufficient permissions", http.MethodGet, "/scope/bar", true, http.StatusForbidden, ``, `more`, `access control error: required permission "more" not granted`, "beta_insufficient_permissions"}, {"by scope: no permission required by endpoint", http.MethodDelete, "/scope/bar", true, http.StatusNoContent, `["a"]`, ``, "", ""}, {"by scope: required permission expression", http.MethodGet, "/scope/path/a/path", true, http.StatusNoContent, `["a"]`, ``, "", ""}, @@ -3782,7 +3782,7 @@ func Test_Permissions(t *testing.T) { {"by role: unauthorized", http.MethodGet, "/role/foo", false, http.StatusUnauthorized, ``, ``, "access control error: roled_jwt: token required", "jwt_token_missing"}, {"by role: sufficient permission", http.MethodGet, "/role/foo", true, http.StatusNoContent, `["a","b"]`, ``, "", ""}, {"by role: permission required by endpoint: insufficient permissions", http.MethodPost, "/role/foo", true, http.StatusForbidden, ``, ``, `access control error: required permission "foo" not granted`, "beta_insufficient_permissions"}, - {"by role: method not permitted", http.MethodDelete, "/role/foo", true, http.StatusMethodNotAllowed, ``, ``, "method not allowed error: method DELETE not allowed by beta_required_permission", ""}, + {"by role: method not permitted", http.MethodDelete, "/role/foo", true, http.StatusMethodNotAllowed, ``, ``, "method not allowed error: method DELETE not allowed by required_permission", ""}, {"by role: permission required by endpoint via *: insufficient permissions", http.MethodGet, "/role/bar", true, http.StatusForbidden, ``, `more`, `access control error: required permission "more" not granted`, "beta_insufficient_permissions"}, {"by role: no permission required by endpoint", http.MethodDelete, "/role/bar", true, http.StatusNoContent, `["a","b"]`, ``, "", ""}, {"by scope/role, mapped from scope", http.MethodGet, "/scope_and_role/foo", true, http.StatusNoContent, `["a","b","c","d","e"]`, ``, "", ""}, diff --git a/server/testdata/integration/config/09_couper.hcl b/server/testdata/integration/config/09_couper.hcl index 87f1fad1c..fa2034206 100644 --- a/server/testdata/integration/config/09_couper.hcl +++ b/server/testdata/integration/config/09_couper.hcl @@ -2,9 +2,9 @@ server "scoped jwt" { api { base_path = "/scope" access_control = ["scoped_jwt"] - beta_required_permission = "z" + required_permission = "z" endpoint "/foo" { - beta_required_permission = { + required_permission = { get = "" post = "foo" } @@ -16,7 +16,7 @@ server "scoped jwt" { } } endpoint "/bar" { - beta_required_permission = { + required_permission = { delete = "" "*" = "more" } @@ -24,7 +24,7 @@ server "scoped jwt" { response { status = 403 headers = { - x-required-permission = request.context.beta_required_permission + x-required-permission = request.context.required_permission } } } @@ -36,7 +36,7 @@ server "scoped jwt" { } } endpoint "/path/{p}/path" { - beta_required_permission = request.path_params.p + required_permission = request.path_params.p response { status = 204 headers = { @@ -45,7 +45,7 @@ server "scoped jwt" { } } endpoint "/object/{method}" { - beta_required_permission = { + required_permission = { (request.path_params.method) = contains(["get", "post"], request.path_params.method) ? "a" : "z" } response { @@ -56,7 +56,7 @@ server "scoped jwt" { } } endpoint "/bad/expression" { - beta_required_permission = request + required_permission = request response { status = 204 headers = { @@ -65,7 +65,7 @@ server "scoped jwt" { } } endpoint "/bad/type/number" { - beta_required_permission = 123 + required_permission = 123 response { status = 204 headers = { @@ -74,7 +74,7 @@ server "scoped jwt" { } } endpoint "/bad/type/boolean" { - beta_required_permission = true + required_permission = true response { status = 204 headers = { @@ -83,7 +83,7 @@ server "scoped jwt" { } } endpoint "/bad/type/tuple" { - beta_required_permission = ["p1", "p2"] + required_permission = ["p1", "p2"] response { status = 204 headers = { @@ -92,7 +92,7 @@ server "scoped jwt" { } } endpoint "/bad/type/null" { - beta_required_permission = null + required_permission = null response { status = 204 headers = { @@ -112,9 +112,9 @@ server "scoped jwt" { api { base_path = "/role" access_control = ["roled_jwt"] - beta_required_permission = "a" + required_permission = "a" endpoint "/foo" { - beta_required_permission = { + required_permission = { get = "" post = "foo" } @@ -126,7 +126,7 @@ server "scoped jwt" { } } endpoint "/bar" { - beta_required_permission = { + required_permission = { delete = "" "*" = "more" } @@ -134,7 +134,7 @@ server "scoped jwt" { response { status = 403 headers = { - x-required-permission = request.context.beta_required_permission + x-required-permission = request.context.required_permission } } } @@ -150,7 +150,7 @@ server "scoped jwt" { base_path = "/scope_and_role" access_control = ["scoped_and_roled_jwt"] endpoint "/foo" { - beta_required_permission = "d" + required_permission = "d" response { status = 204 headers = { @@ -159,7 +159,7 @@ server "scoped jwt" { } } endpoint "/bar" { - beta_required_permission = "e" + required_permission = "e" response { status = 204 headers = { @@ -172,7 +172,7 @@ server "scoped jwt" { base_path = "/scope_and_role_files" access_control = ["scoped_and_roled_jwt_files"] endpoint "/foo" { - beta_required_permission = "d" + required_permission = "d" response { status = 204 headers = { @@ -181,7 +181,7 @@ server "scoped jwt" { } } endpoint "/bar" { - beta_required_permission = "e" + required_permission = "e" response { status = 204 headers = { diff --git a/server/testdata/integration/config/11_couper.hcl b/server/testdata/integration/config/11_couper.hcl index 830ebff38..6c766798c 100644 --- a/server/testdata/integration/config/11_couper.hcl +++ b/server/testdata/integration/config/11_couper.hcl @@ -25,7 +25,7 @@ server { endpoint "/unrestricted" { access_control = ["token"] - beta_required_permission = { + required_permission = { get = "foo" head = "foo" post = "foo" @@ -42,7 +42,7 @@ server { endpoint "/restricted" { access_control = ["token"] allowed_methods = ["GET", "Post", "delete", "BREW"] - beta_required_permission = { + required_permission = { get = "foo" head = "foo" post = "foo" @@ -59,7 +59,7 @@ server { endpoint "/wildcard" { allowed_methods = ["*"] - beta_required_permission = "" + required_permission = "" response { body = "a" @@ -68,7 +68,7 @@ server { endpoint "/wildcardAndMore" { allowed_methods = ["get", "*", "PuT", "brew"] - beta_required_permission = "" + required_permission = "" response { body = "a" diff --git a/server/testdata/integration/error_handler/04_couper.hcl b/server/testdata/integration/error_handler/04_couper.hcl index 1dfbf63fc..33df8e214 100644 --- a/server/testdata/integration/error_handler/04_couper.hcl +++ b/server/testdata/integration/error_handler/04_couper.hcl @@ -5,7 +5,7 @@ server "scoped" { api { base_path = "/api" - beta_required_permission = "read" + required_permission = "read" endpoint "/" { response { status = 204 @@ -13,7 +13,7 @@ server "scoped" { } endpoint "/pow/" { - beta_required_permission = { + required_permission = { post = "power" } @@ -48,7 +48,7 @@ server "scoped" { } endpoint "/" { - beta_required_permission = "power" + required_permission = "power" response { status = 204 @@ -74,7 +74,7 @@ server "scoped" { } endpoint "/" { - beta_required_permission = "power" + required_permission = "power" response { status = 204 @@ -90,7 +90,7 @@ server "scoped" { } endpoint "/" { - beta_required_permission = "write" + required_permission = "write" response { body = "OK" diff --git a/server/testdata/integration/logs/01_couper.hcl b/server/testdata/integration/logs/01_couper.hcl index cf80a5837..46bd34275 100644 --- a/server/testdata/integration/logs/01_couper.hcl +++ b/server/testdata/integration/logs/01_couper.hcl @@ -156,7 +156,7 @@ server "logs" { endpoint "/error-handler/endpoint" { access_control = ["JWT"] - beta_required_permission = "required" + required_permission = "required" response { status = 204 diff --git a/server/testdata/multi/server/couper.d/couper.hcl b/server/testdata/multi/server/couper.d/couper.hcl index a48a73677..097aa9c56 100644 --- a/server/testdata/multi/server/couper.d/couper.hcl +++ b/server/testdata/multi/server/couper.d/couper.hcl @@ -20,7 +20,7 @@ server { api "ERR" { access_control = ["scoped"] - beta_required_permission = { + required_permission = { GET = "gimme" } error_handler "beta_insufficient_permissions" "unexpected_status" "*" { From 8f34bc3ddb7b6511047cd0c16ca3b163b92e7e5e Mon Sep 17 00:00:00 2001 From: Johannes Koch Date: Tue, 17 Jan 2023 10:15:32 +0100 Subject: [PATCH 05/14] betaRequiredPermission -> requiredPermission --- eval/context.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/eval/context.go b/eval/context.go index b68941dd7..5be66e44e 100644 --- a/eval/context.go +++ b/eval/context.go @@ -554,13 +554,13 @@ func NewRawOrigin(u *url.URL) *url.URL { } const ( - grantedPermissions = "granted_permissions" - betaRequiredPermission = "required_permission" + grantedPermissions = "granted_permissions" + requiredPermission = "required_permission" ) func IsReservedContextName(name string) bool { switch name { - case grantedPermissions, betaRequiredPermission: + case grantedPermissions, requiredPermission: return true } @@ -581,8 +581,8 @@ func newVariable(ctx context.Context, cookies []*http.Cookie, headers http.Heade if len(gp) > 0 { ctxAcMap[grantedPermissions] = seetie.GoToValue(gp) } - if requiredPermission, permissionSet := ctx.Value(request.BetaRequiredPermission).(string); permissionSet { - ctxAcMap[betaRequiredPermission] = seetie.GoToValue(requiredPermission) + if rp, permissionSet := ctx.Value(request.BetaRequiredPermission).(string); permissionSet { + ctxAcMap[requiredPermission] = seetie.GoToValue(rp) } var ctxAcMapValue cty.Value if len(ctxAcMap) > 0 { From 39d550227be72bb9c5b7dfb126d25484a2c85b07 Mon Sep 17 00:00:00 2001 From: Johannes Koch Date: Tue, 17 Jan 2023 10:21:52 +0100 Subject: [PATCH 06/14] request.BetaRequiredPermission -> request.RequiredPermission --- accesscontrol/permissions.go | 2 +- config/request/context_key.go | 2 +- eval/context.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/accesscontrol/permissions.go b/accesscontrol/permissions.go index 274b71508..59fa52d84 100644 --- a/accesscontrol/permissions.go +++ b/accesscontrol/permissions.go @@ -93,7 +93,7 @@ func (p *PermissionsControl) Validate(req *http.Request) error { } ctx := req.Context() - ctx = context.WithValue(ctx, request.BetaRequiredPermission, requiredPermission) + ctx = context.WithValue(ctx, request.RequiredPermission, requiredPermission) *req = *req.WithContext(ctx) evalCtx := eval.ContextFromRequest(req) diff --git a/config/request/context_key.go b/config/request/context_key.go index 912d8be54..1499ebb0a 100644 --- a/config/request/context_key.go +++ b/config/request/context_key.go @@ -9,7 +9,6 @@ const ( BackendBytes BackendName BackendParams - BetaRequiredPermission BufferOptions ConfigDryRun ConnectTimeout @@ -28,6 +27,7 @@ const ( LogEntry OpenAPI PathParams + RequiredPermission ResponseBlock ResponseWriter RoundTripName diff --git a/eval/context.go b/eval/context.go index 5be66e44e..4710fd554 100644 --- a/eval/context.go +++ b/eval/context.go @@ -581,7 +581,7 @@ func newVariable(ctx context.Context, cookies []*http.Cookie, headers http.Heade if len(gp) > 0 { ctxAcMap[grantedPermissions] = seetie.GoToValue(gp) } - if rp, permissionSet := ctx.Value(request.BetaRequiredPermission).(string); permissionSet { + if rp, permissionSet := ctx.Value(request.RequiredPermission).(string); permissionSet { ctxAcMap[requiredPermission] = seetie.GoToValue(rp) } var ctxAcMapValue cty.Value From 98871f20a83dec5ebbb456fdff73934130f01f1e Mon Sep 17 00:00:00 2001 From: Johannes Koch Date: Tue, 17 Jan 2023 10:36:42 +0100 Subject: [PATCH 07/14] beta_insufficient_permissions -> insufficient_permissions, errors.BetaInsufficientPermissions -> errors.InsufficientPermissions --- accesscontrol/permissions.go | 4 ++-- config/api.go | 2 +- config/endpoint.go | 2 +- docs/website/content/2.configuration/4.block/api.md | 2 +- .../content/2.configuration/4.block/endpoint.md | 2 +- .../content/2.configuration/7.error-handling.md | 4 ++-- errors/type_defintions.go | 2 +- errors/types_generated.go | 6 +++--- server/http_integration_test.go | 12 ++++++------ server/testdata/integration/config/09_couper.hcl | 4 ++-- .../testdata/integration/error_handler/04_couper.hcl | 10 +++++----- server/testdata/integration/logs/01_couper.hcl | 2 +- server/testdata/multi/server/couper.d/couper.hcl | 4 ++-- server/testdata/multi/server/couper.hcl | 4 ++-- 14 files changed, 30 insertions(+), 30 deletions(-) diff --git a/accesscontrol/permissions.go b/accesscontrol/permissions.go index 59fa52d84..b99f7418a 100644 --- a/accesscontrol/permissions.go +++ b/accesscontrol/permissions.go @@ -101,10 +101,10 @@ func (p *PermissionsControl) Validate(req *http.Request) error { grantedPermission, ok := ctx.Value(request.GrantedPermissions).([]string) if !ok { - return errors.BetaInsufficientPermissions.Messagef("no permissions granted") + return errors.InsufficientPermissions.Messagef("no permissions granted") } if !hasGrantedPermission(grantedPermission, requiredPermission) { - return errors.BetaInsufficientPermissions.Messagef("required permission %q not granted", requiredPermission) + return errors.InsufficientPermissions.Messagef("required permission %q not granted", requiredPermission) } return nil } diff --git a/config/api.go b/config/api.go index 7fff6ba0d..7a0bec2a0 100644 --- a/config/api.go +++ b/config/api.go @@ -44,7 +44,7 @@ func (a API) Inline() interface{} { type Inline struct { meta.ResponseHeadersAttributes meta.LogFieldsAttribute - RequiredPermission hcl.Expression `hcl:"required_permission,optional" docs:"Permission required to use this API (see [error type](/configuration/error-handling#error-types) {beta_insufficient_permissions})." type:"string or object (string)"` + RequiredPermission hcl.Expression `hcl:"required_permission,optional" docs:"Permission required to use this API (see [error type](/configuration/error-handling#error-types) {insufficient_permissions})." type:"string or object (string)"` } return &Inline{} diff --git a/config/endpoint.go b/config/endpoint.go index 289b87345..d2510695e 100644 --- a/config/endpoint.go +++ b/config/endpoint.go @@ -51,7 +51,7 @@ func (e Endpoint) Inline() interface{} { meta.QueryParamsAttributes meta.LogFieldsAttribute ResponseStatus *uint8 `hcl:"set_response_status,optional" docs:"Modifies the response status code."` - RequiredPermission hcl.Expression `hcl:"required_permission,optional" docs:"Permission required to use this endpoint (see [error type](/configuration/error-handling#error-types) {beta_insufficient_permissions})." type:"string or object (string)"` + RequiredPermission hcl.Expression `hcl:"required_permission,optional" docs:"Permission required to use this endpoint (see [error type](/configuration/error-handling#error-types) {insufficient_permissions})." type:"string or object (string)"` } return &Inline{} diff --git a/docs/website/content/2.configuration/4.block/api.md b/docs/website/content/2.configuration/4.block/api.md index 9fcda96b7..96d2ffa70 100644 --- a/docs/website/content/2.configuration/4.block/api.md +++ b/docs/website/content/2.configuration/4.block/api.md @@ -84,7 +84,7 @@ values: [ }, { "default": "", - "description": "Permission required to use this API (see [error type](/configuration/error-handling#error-types) `beta_insufficient_permissions`).", + "description": "Permission required to use this API (see [error type](/configuration/error-handling#error-types) `insufficient_permissions`).", "name": "required_permission", "type": "string or object (string)" }, diff --git a/docs/website/content/2.configuration/4.block/endpoint.md b/docs/website/content/2.configuration/4.block/endpoint.md index 4f4de0248..3ef940de4 100644 --- a/docs/website/content/2.configuration/4.block/endpoint.md +++ b/docs/website/content/2.configuration/4.block/endpoint.md @@ -132,7 +132,7 @@ values: [ }, { "default": "", - "description": "Permission required to use this endpoint (see [error type](/configuration/error-handling#error-types) `beta_insufficient_permissions`).", + "description": "Permission required to use this endpoint (see [error type](/configuration/error-handling#error-types) `insufficient_permissions`).", "name": "required_permission", "type": "string or object (string)" }, diff --git a/docs/website/content/2.configuration/7.error-handling.md b/docs/website/content/2.configuration/7.error-handling.md index cef83f1db..76eb43391 100644 --- a/docs/website/content/2.configuration/7.error-handling.md +++ b/docs/website/content/2.configuration/7.error-handling.md @@ -61,7 +61,7 @@ The following table documents error types that can be handled in `api` blocks: | `backend_unhealthy` (`backend`) | A backend is unhealthy and will not send the request | Send error template with status `502`. | | `beta_backend_token_request` (`backend`) | A token request for the backend has failed | Send error template with status `502`. | | `access_control` | Access control related errors | Send error template with status `403`. | -| `beta_insufficient_permissions` (`access_control`) | The permission required for the requested operation is not in the permissions granted to the requester. | Send error template with status `403`. | +| `insufficient_permissions` (`access_control`) | The permission required for the requested operation is not in the permissions granted to the requester. | Send error template with status `403`. | ### Endpoint error types @@ -76,7 +76,7 @@ The following table documents error types that can be handled in `endpoint` bloc | `beta_backend_token_request` (`backend`) | A token request for the backend has failed | Send error template with status `502`. | | `access_control` | Access control related errors | Send error template with status `403`. | | `beta_backend_rate_limit_exceeded` | Backend rate limit related errors | Send error template with status `429`. | -| `beta_insufficient_permissions` (`access_control`) | The permission required for the requested operation is not in the permissions granted to the requester. | Send error template with status `403`. | +| `insufficient_permissions` (`access_control`) | The permission required for the requested operation is not in the permissions granted to the requester. | Send error template with status `403`. | | `endpoint` | All catchable `endpoint` related errors | Send error template with status `502`. | | `sequence` (`endpoint`) | A `request` or `proxy` block request has been failed while depending on another one | Send error template with status `502`. | | `unexpected_status` (`endpoint`) | A `request` or `proxy` block response status code does not match the to `expected_status` list | Send error template with status `502`. | diff --git a/errors/type_defintions.go b/errors/type_defintions.go index 0c467c56d..22685421b 100644 --- a/errors/type_defintions.go +++ b/errors/type_defintions.go @@ -20,7 +20,7 @@ var Definitions = []*Error{ AccessControl.Kind("saml2"), AccessControl.Kind("saml2").Kind("saml"), - AccessControl.Kind("beta_insufficient_permissions").Context("api").Context("endpoint"), + AccessControl.Kind("insufficient_permissions").Context("api").Context("endpoint"), Backend, Backend.Kind("backend_openapi_validation").Status(http.StatusBadRequest), diff --git a/errors/types_generated.go b/errors/types_generated.go index 9bbdc8fb8..e15d899c0 100644 --- a/errors/types_generated.go +++ b/errors/types_generated.go @@ -12,7 +12,7 @@ var ( Oauth2 = Definitions[7] Saml2 = Definitions[8] Saml = Definitions[9] - BetaInsufficientPermissions = Definitions[10] + InsufficientPermissions = Definitions[10] BackendOpenapiValidation = Definitions[12] BetaBackendRateLimitExceeded = Definitions[13] BackendTimeout = Definitions[14] @@ -39,7 +39,7 @@ var types = typeDefinitions{ "oauth2": Oauth2, "saml2": Saml2, "saml": Saml, - "beta_insufficient_permissions": BetaInsufficientPermissions, + "insufficient_permissions": InsufficientPermissions, "backend": Backend, "backend_openapi_validation": BackendOpenapiValidation, "beta_backend_rate_limit_exceeded": BetaBackendRateLimitExceeded, @@ -60,4 +60,4 @@ func IsKnown(errorType string) bool { // SuperTypesMapsByContext holds maps for error super-types to sub-types // by a given context block type (e.g. api or endpoint). -var SuperTypesMapsByContext = map[string]map[string][]string{"api": map[string][]string{"*": []string{"beta_insufficient_permissions", "backend_openapi_validation", "beta_backend_rate_limit_exceeded", "backend_timeout", "beta_backend_token_request", "backend_unhealthy"}, "access_control": []string{"beta_insufficient_permissions"}, "backend": []string{"backend_openapi_validation", "beta_backend_rate_limit_exceeded", "backend_timeout", "beta_backend_token_request", "backend_unhealthy"}}, "endpoint": map[string][]string{"*": []string{"beta_insufficient_permissions", "backend_openapi_validation", "beta_backend_rate_limit_exceeded", "backend_timeout", "beta_backend_token_request", "backend_unhealthy", "sequence", "unexpected_status"}, "access_control": []string{"beta_insufficient_permissions"}, "backend": []string{"backend_openapi_validation", "beta_backend_rate_limit_exceeded", "backend_timeout", "beta_backend_token_request", "backend_unhealthy"}, "endpoint": []string{"sequence", "unexpected_status"}}} +var SuperTypesMapsByContext = map[string]map[string][]string{"api": map[string][]string{"*": []string{"insufficient_permissions", "backend_openapi_validation", "beta_backend_rate_limit_exceeded", "backend_timeout", "beta_backend_token_request", "backend_unhealthy"}, "access_control": []string{"insufficient_permissions"}, "backend": []string{"backend_openapi_validation", "beta_backend_rate_limit_exceeded", "backend_timeout", "beta_backend_token_request", "backend_unhealthy"}}, "endpoint": map[string][]string{"*": []string{"insufficient_permissions", "backend_openapi_validation", "beta_backend_rate_limit_exceeded", "backend_timeout", "beta_backend_token_request", "backend_unhealthy", "sequence", "unexpected_status"}, "access_control": []string{"insufficient_permissions"}, "backend": []string{"backend_openapi_validation", "beta_backend_rate_limit_exceeded", "backend_timeout", "beta_backend_token_request", "backend_unhealthy"}, "endpoint": []string{"sequence", "unexpected_status"}}} diff --git a/server/http_integration_test.go b/server/http_integration_test.go index eab92d0fa..cd7950268 100644 --- a/server/http_integration_test.go +++ b/server/http_integration_test.go @@ -3766,24 +3766,24 @@ func Test_Permissions(t *testing.T) { for _, tc := range []testCase{ {"by scope: unauthorized", http.MethodGet, "/scope/foo", false, http.StatusUnauthorized, ``, ``, "access control error: scoped_jwt: token required", "jwt_token_missing"}, {"by scope: no permission required by endpoint", http.MethodGet, "/scope/foo", true, http.StatusNoContent, `["a"]`, ``, "", ""}, - {"by scope: permission required by endpoint: insufficient permissions", http.MethodPost, "/scope/foo", true, http.StatusForbidden, ``, ``, `access control error: required permission "foo" not granted`, "beta_insufficient_permissions"}, + {"by scope: permission required by endpoint: insufficient permissions", http.MethodPost, "/scope/foo", true, http.StatusForbidden, ``, ``, `access control error: required permission "foo" not granted`, "insufficient_permissions"}, {"by scope: method not permitted", http.MethodDelete, "/scope/foo", true, http.StatusMethodNotAllowed, ``, ``, "method not allowed error: method DELETE not allowed by required_permission", ""}, - {"by scope: permission required by endpoint via *: insufficient permissions", http.MethodGet, "/scope/bar", true, http.StatusForbidden, ``, `more`, `access control error: required permission "more" not granted`, "beta_insufficient_permissions"}, + {"by scope: permission required by endpoint via *: insufficient permissions", http.MethodGet, "/scope/bar", true, http.StatusForbidden, ``, `more`, `access control error: required permission "more" not granted`, "insufficient_permissions"}, {"by scope: no permission required by endpoint", http.MethodDelete, "/scope/bar", true, http.StatusNoContent, `["a"]`, ``, "", ""}, {"by scope: required permission expression", http.MethodGet, "/scope/path/a/path", true, http.StatusNoContent, `["a"]`, ``, "", ""}, {"by scope: required permission object expression (GET)", http.MethodGet, "/scope/object/get", true, http.StatusNoContent, `["a"]`, ``, "", ""}, - {"by scope: required permission object expression (DELETE)", http.MethodDelete, "/scope/object/delete", true, http.StatusForbidden, ``, ``, `access control error: required permission "z" not granted`, "beta_insufficient_permissions"}, + {"by scope: required permission object expression (DELETE)", http.MethodDelete, "/scope/object/delete", true, http.StatusForbidden, ``, ``, `access control error: required permission "z" not granted`, "insufficient_permissions"}, {"by scope: required permission bad expression", http.MethodGet, "/scope/bad/expression", true, http.StatusInternalServerError, ``, ``, "expression evaluation error", "evaluation"}, {"by scope: required permission bad type number", http.MethodGet, "/scope/bad/type/number", true, http.StatusInternalServerError, ``, ``, "expression evaluation error", "evaluation"}, {"by scope: required permission bad type boolean", http.MethodGet, "/scope/bad/type/boolean", true, http.StatusInternalServerError, ``, ``, "expression evaluation error", "evaluation"}, {"by scope: required permission bad type tuple", http.MethodGet, "/scope/bad/type/tuple", true, http.StatusInternalServerError, ``, ``, "expression evaluation error", "evaluation"}, {"by scope: required permission bad type null", http.MethodGet, "/scope/bad/type/null", true, http.StatusInternalServerError, ``, ``, "expression evaluation error", "evaluation"}, - {"by scope: required permission by api only: insufficient permissions", http.MethodGet, "/scope/permission-from-api", true, http.StatusForbidden, ``, ``, `access control error: required permission "z" not granted`, "beta_insufficient_permissions"}, + {"by scope: required permission by api only: insufficient permissions", http.MethodGet, "/scope/permission-from-api", true, http.StatusForbidden, ``, ``, `access control error: required permission "z" not granted`, "insufficient_permissions"}, {"by role: unauthorized", http.MethodGet, "/role/foo", false, http.StatusUnauthorized, ``, ``, "access control error: roled_jwt: token required", "jwt_token_missing"}, {"by role: sufficient permission", http.MethodGet, "/role/foo", true, http.StatusNoContent, `["a","b"]`, ``, "", ""}, - {"by role: permission required by endpoint: insufficient permissions", http.MethodPost, "/role/foo", true, http.StatusForbidden, ``, ``, `access control error: required permission "foo" not granted`, "beta_insufficient_permissions"}, + {"by role: permission required by endpoint: insufficient permissions", http.MethodPost, "/role/foo", true, http.StatusForbidden, ``, ``, `access control error: required permission "foo" not granted`, "insufficient_permissions"}, {"by role: method not permitted", http.MethodDelete, "/role/foo", true, http.StatusMethodNotAllowed, ``, ``, "method not allowed error: method DELETE not allowed by required_permission", ""}, - {"by role: permission required by endpoint via *: insufficient permissions", http.MethodGet, "/role/bar", true, http.StatusForbidden, ``, `more`, `access control error: required permission "more" not granted`, "beta_insufficient_permissions"}, + {"by role: permission required by endpoint via *: insufficient permissions", http.MethodGet, "/role/bar", true, http.StatusForbidden, ``, `more`, `access control error: required permission "more" not granted`, "insufficient_permissions"}, {"by role: no permission required by endpoint", http.MethodDelete, "/role/bar", true, http.StatusNoContent, `["a","b"]`, ``, "", ""}, {"by scope/role, mapped from scope", http.MethodGet, "/scope_and_role/foo", true, http.StatusNoContent, `["a","b","c","d","e"]`, ``, "", ""}, {"by scope/role, mapped scope mapped from role", http.MethodGet, "/scope_and_role/bar", true, http.StatusNoContent, `["a","b","c","d","e"]`, ``, "", ""}, diff --git a/server/testdata/integration/config/09_couper.hcl b/server/testdata/integration/config/09_couper.hcl index fa2034206..61a95921e 100644 --- a/server/testdata/integration/config/09_couper.hcl +++ b/server/testdata/integration/config/09_couper.hcl @@ -20,7 +20,7 @@ server "scoped jwt" { delete = "" "*" = "more" } - error_handler "beta_insufficient_permissions" { + error_handler "insufficient_permissions" { response { status = 403 headers = { @@ -130,7 +130,7 @@ server "scoped jwt" { delete = "" "*" = "more" } - error_handler "beta_insufficient_permissions" { + error_handler "insufficient_permissions" { response { status = 403 headers = { diff --git a/server/testdata/integration/error_handler/04_couper.hcl b/server/testdata/integration/error_handler/04_couper.hcl index 33df8e214..5316763b6 100644 --- a/server/testdata/integration/error_handler/04_couper.hcl +++ b/server/testdata/integration/error_handler/04_couper.hcl @@ -21,7 +21,7 @@ server "scoped" { status = 204 } - error_handler "beta_insufficient_permissions" { + error_handler "insufficient_permissions" { response { status = 400 body = "Not enough power" @@ -29,7 +29,7 @@ server "scoped" { } } - error_handler "beta_insufficient_permissions" { + error_handler "insufficient_permissions" { response { status = 418 } @@ -40,7 +40,7 @@ server "scoped" { api { base_path = "/wildcard1" - error_handler "beta_insufficient_permissions" { + error_handler "insufficient_permissions" { response { status = 418 body = "Not enough power" @@ -80,7 +80,7 @@ server "scoped" { status = 204 } - error_handler "beta_insufficient_permissions" { + error_handler "insufficient_permissions" { response { status = 400 body = "Not enough power" @@ -96,7 +96,7 @@ server "scoped" { body = "OK" } - error_handler "beta_insufficient_permissions" { + error_handler "insufficient_permissions" { response { status = 418 } diff --git a/server/testdata/integration/logs/01_couper.hcl b/server/testdata/integration/logs/01_couper.hcl index 46bd34275..8b578293a 100644 --- a/server/testdata/integration/logs/01_couper.hcl +++ b/server/testdata/integration/logs/01_couper.hcl @@ -162,7 +162,7 @@ server "logs" { status = 204 } - error_handler "beta_insufficient_permissions" { + error_handler "insufficient_permissions" { custom_log_fields = { error_handler = request.method } diff --git a/server/testdata/multi/server/couper.d/couper.hcl b/server/testdata/multi/server/couper.d/couper.hcl index 097aa9c56..c3b925900 100644 --- a/server/testdata/multi/server/couper.d/couper.hcl +++ b/server/testdata/multi/server/couper.d/couper.hcl @@ -23,7 +23,7 @@ server { required_permission = { GET = "gimme" } - error_handler "beta_insufficient_permissions" "unexpected_status" "*" { + error_handler "insufficient_permissions" "unexpected_status" "*" { response { status = 418 } @@ -34,7 +34,7 @@ server { base_path = "/api-111" access_control = ["foo"] - error_handler "beta_insufficient_permissions" { + error_handler "insufficient_permissions" { response { status = 415 } diff --git a/server/testdata/multi/server/couper.hcl b/server/testdata/multi/server/couper.hcl index 4528b99f7..bf3025db7 100644 --- a/server/testdata/multi/server/couper.hcl +++ b/server/testdata/multi/server/couper.hcl @@ -29,7 +29,7 @@ server { } } - error_handler "unexpected_status * beta_insufficient_permissions" { + error_handler "unexpected_status * insufficient_permissions" { response { status = 405 } @@ -39,7 +39,7 @@ server { api "API" { base_path = "/api-1" - error_handler "beta_insufficient_permissions" { + error_handler "insufficient_permissions" { response { status = 401 } From 092e47ab9f145e3c46b6fec8ea51d86e40102c78 Mon Sep 17 00:00:00 2001 From: Johannes Koch Date: Tue, 17 Jan 2023 10:48:14 +0100 Subject: [PATCH 08/14] beta_permissions_map_file -> permissions_map_file --- accesscontrol/jwt_test.go | 8 ++++---- config/ac_jwt.go | 4 ++-- .../website/content/2.configuration/4.block/jwt.md | 14 +++++++------- server/testdata/integration/config/09_couper.hcl | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/accesscontrol/jwt_test.go b/accesscontrol/jwt_test.go index 9ca387061..037b11dd0 100644 --- a/accesscontrol/jwt_test.go +++ b/accesscontrol/jwt_test.go @@ -746,7 +746,7 @@ func TestJwtConfig(t *testing.T) { "configuration error: myac: roles map: read error: open .*/testdata/file_not_found: no such file or directory", }, { - "signature_algorithm, both beta_permissions_map and beta_permissions_map_file", + "signature_algorithm, both beta_permissions_map and permissions_map_file", ` server "test" {} definitions { @@ -755,14 +755,14 @@ func TestJwtConfig(t *testing.T) { header = "..." key = "..." beta_permissions_map = {} - beta_permissions_map_file = "testdata/map.json" + permissions_map_file = "testdata/map.json" } } `, "configuration error: myac: jwt permissions map: read error: configured attribute and file", }, { - "signature_algorithm, beta_permissions_map_file not found", + "signature_algorithm, permissions_map_file not found", ` server "test" {} definitions { @@ -770,7 +770,7 @@ func TestJwtConfig(t *testing.T) { signature_algorithm = "HS256" header = "..." key = "..." - beta_permissions_map_file = "file_not_found" + permissions_map_file = "file_not_found" } } `, diff --git a/config/ac_jwt.go b/config/ac_jwt.go index 085d47a98..e1db48989 100644 --- a/config/ac_jwt.go +++ b/config/ac_jwt.go @@ -40,8 +40,8 @@ type JWT struct { RolesMap map[string][]string `hcl:"beta_roles_map,optional" docs:"Mapping of roles to granted permissions. Non-mapped roles can be assigned with {*} to specific permissions. Mutually exclusive with {beta_roles_map_file}."` RolesMapFile string `hcl:"beta_roles_map_file,optional" docs:"Reference to JSON file containing role mappings. Mutually exclusive with {beta_roles_map}. See {beta_roles_map} for more information."` PermissionsClaim string `hcl:"beta_permissions_claim,optional" docs:"Name of claim containing the granted permissions. The claim value must either be a string containing a space-separated list of permissions or a list of string permissions."` - PermissionsMap map[string][]string `hcl:"beta_permissions_map,optional" docs:"Mapping of granted permissions to additional granted permissions. Maps values from {beta_permissions_claim} and those created from {beta_roles_map}. The map is called recursively. Mutually exclusive with {beta_permissions_map_file}."` - PermissionsMapFile string `hcl:"beta_permissions_map_file,optional" docs:"Reference to JSON file containing permission mappings. Mutually exclusive with {beta_permissions_map}. See {beta_permissions_map} for more information."` + PermissionsMap map[string][]string `hcl:"beta_permissions_map,optional" docs:"Mapping of granted permissions to additional granted permissions. Maps values from {beta_permissions_claim} and those created from {beta_roles_map}. The map is called recursively. Mutually exclusive with {permissions_map_file}."` + PermissionsMapFile string `hcl:"permissions_map_file,optional" docs:"Reference to JSON file containing permission mappings. Mutually exclusive with {beta_permissions_map}. See {beta_permissions_map} for more information."` SignatureAlgorithm string `hcl:"signature_algorithm,optional" docs:"Valid values: {RS256}, {RS384}, {RS512}, {HS256}, {HS384}, {HS512}, {ES256}, {ES384}, {ES512}"` SigningKey string `hcl:"signing_key,optional" docs:"Private key (in PEM format) for {RS*} and {ES*} variants. Mutually exclusive with {signing_key_file}."` SigningKeyFile string `hcl:"signing_key_file,optional" docs:"Reference to file containing signing key. Mutually exclusive with {signing_key}. See {signing_key} for more information."` diff --git a/docs/website/content/2.configuration/4.block/jwt.md b/docs/website/content/2.configuration/4.block/jwt.md index d3a567f14..7d6ed071d 100644 --- a/docs/website/content/2.configuration/4.block/jwt.md +++ b/docs/website/content/2.configuration/4.block/jwt.md @@ -28,16 +28,10 @@ values: [ }, { "default": "", - "description": "Mapping of granted permissions to additional granted permissions. Maps values from `beta_permissions_claim` and those created from `beta_roles_map`. The map is called recursively. Mutually exclusive with `beta_permissions_map_file`.", + "description": "Mapping of granted permissions to additional granted permissions. Maps values from `beta_permissions_claim` and those created from `beta_roles_map`. The map is called recursively. Mutually exclusive with `permissions_map_file`.", "name": "beta_permissions_map", "type": "object" }, - { - "default": "", - "description": "Reference to JSON file containing permission mappings. Mutually exclusive with `beta_permissions_map`. See `beta_permissions_map` for more information.", - "name": "beta_permissions_map_file", - "type": "string" - }, { "default": "", "description": "Name of claim specifying the roles of the user represented by the token. The claim value must either be a string containing a space-separated list of role values or a list of string role values.", @@ -116,6 +110,12 @@ values: [ "name": "key_file", "type": "string" }, + { + "default": "", + "description": "Reference to JSON file containing permission mappings. Mutually exclusive with `beta_permissions_map`. See `beta_permissions_map` for more information.", + "name": "permissions_map_file", + "type": "string" + }, { "default": "[]", "description": "List of claim names that must be given for a valid token.", diff --git a/server/testdata/integration/config/09_couper.hcl b/server/testdata/integration/config/09_couper.hcl index 61a95921e..3bde4d8c5 100644 --- a/server/testdata/integration/config/09_couper.hcl +++ b/server/testdata/integration/config/09_couper.hcl @@ -230,6 +230,6 @@ definitions { beta_permissions_claim = "scp" beta_roles_claim = "rl" beta_roles_map_file = "testdata/integration/config/roles.json" - beta_permissions_map_file = "testdata/integration/config/permissions.json" + permissions_map_file = "testdata/integration/config/permissions.json" } } From 53cfa96f0d1369308e9acf470ea67f38b46e737d Mon Sep 17 00:00:00 2001 From: Johannes Koch Date: Tue, 17 Jan 2023 10:56:17 +0100 Subject: [PATCH 09/14] beta_permissions_map -> permissions_map --- accesscontrol/jwt_test.go | 4 ++-- config/ac_jwt.go | 4 ++-- config/configload/validate_test.go | 4 ++-- .../website/content/2.configuration/4.block/jwt.md | 14 +++++++------- server/testdata/integration/config/09_couper.hcl | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/accesscontrol/jwt_test.go b/accesscontrol/jwt_test.go index 037b11dd0..04be6a550 100644 --- a/accesscontrol/jwt_test.go +++ b/accesscontrol/jwt_test.go @@ -746,7 +746,7 @@ func TestJwtConfig(t *testing.T) { "configuration error: myac: roles map: read error: open .*/testdata/file_not_found: no such file or directory", }, { - "signature_algorithm, both beta_permissions_map and permissions_map_file", + "signature_algorithm, both permissions_map and permissions_map_file", ` server "test" {} definitions { @@ -754,7 +754,7 @@ func TestJwtConfig(t *testing.T) { signature_algorithm = "HS256" header = "..." key = "..." - beta_permissions_map = {} + permissions_map = {} permissions_map_file = "testdata/map.json" } } diff --git a/config/ac_jwt.go b/config/ac_jwt.go index e1db48989..afc61436c 100644 --- a/config/ac_jwt.go +++ b/config/ac_jwt.go @@ -40,8 +40,8 @@ type JWT struct { RolesMap map[string][]string `hcl:"beta_roles_map,optional" docs:"Mapping of roles to granted permissions. Non-mapped roles can be assigned with {*} to specific permissions. Mutually exclusive with {beta_roles_map_file}."` RolesMapFile string `hcl:"beta_roles_map_file,optional" docs:"Reference to JSON file containing role mappings. Mutually exclusive with {beta_roles_map}. See {beta_roles_map} for more information."` PermissionsClaim string `hcl:"beta_permissions_claim,optional" docs:"Name of claim containing the granted permissions. The claim value must either be a string containing a space-separated list of permissions or a list of string permissions."` - PermissionsMap map[string][]string `hcl:"beta_permissions_map,optional" docs:"Mapping of granted permissions to additional granted permissions. Maps values from {beta_permissions_claim} and those created from {beta_roles_map}. The map is called recursively. Mutually exclusive with {permissions_map_file}."` - PermissionsMapFile string `hcl:"permissions_map_file,optional" docs:"Reference to JSON file containing permission mappings. Mutually exclusive with {beta_permissions_map}. See {beta_permissions_map} for more information."` + PermissionsMap map[string][]string `hcl:"permissions_map,optional" docs:"Mapping of granted permissions to additional granted permissions. Maps values from {beta_permissions_claim} and those created from {beta_roles_map}. The map is called recursively. Mutually exclusive with {permissions_map_file}."` + PermissionsMapFile string `hcl:"permissions_map_file,optional" docs:"Reference to JSON file containing permission mappings. Mutually exclusive with {permissions_map}. See {permissions_map} for more information."` SignatureAlgorithm string `hcl:"signature_algorithm,optional" docs:"Valid values: {RS256}, {RS384}, {RS512}, {HS256}, {HS384}, {HS512}, {ES256}, {ES384}, {ES512}"` SigningKey string `hcl:"signing_key,optional" docs:"Private key (in PEM format) for {RS*} and {ES*} variants. Mutually exclusive with {signing_key_file}."` SigningKeyFile string `hcl:"signing_key_file,optional" docs:"Reference to file containing signing key. Mutually exclusive with {signing_key}. See {signing_key} for more information."` diff --git a/config/configload/validate_test.go b/config/configload/validate_test.go index 795c7a101..5e1329a09 100644 --- a/config/configload/validate_test.go +++ b/config/configload/validate_test.go @@ -1268,13 +1268,13 @@ definitions { "", }, { - "beta_permissions_map", + "permissions_map", `server {} definitions { jwt "a" { signature_algorithm = "HS256" key = "asdf" - beta_permissions_map = { + permissions_map = { a = [] A = [] } diff --git a/docs/website/content/2.configuration/4.block/jwt.md b/docs/website/content/2.configuration/4.block/jwt.md index 7d6ed071d..dc614c97f 100644 --- a/docs/website/content/2.configuration/4.block/jwt.md +++ b/docs/website/content/2.configuration/4.block/jwt.md @@ -26,12 +26,6 @@ values: [ "name": "beta_permissions_claim", "type": "string" }, - { - "default": "", - "description": "Mapping of granted permissions to additional granted permissions. Maps values from `beta_permissions_claim` and those created from `beta_roles_map`. The map is called recursively. Mutually exclusive with `permissions_map_file`.", - "name": "beta_permissions_map", - "type": "object" - }, { "default": "", "description": "Name of claim specifying the roles of the user represented by the token. The claim value must either be a string containing a space-separated list of role values or a list of string role values.", @@ -112,7 +106,13 @@ values: [ }, { "default": "", - "description": "Reference to JSON file containing permission mappings. Mutually exclusive with `beta_permissions_map`. See `beta_permissions_map` for more information.", + "description": "Mapping of granted permissions to additional granted permissions. Maps values from `beta_permissions_claim` and those created from `beta_roles_map`. The map is called recursively. Mutually exclusive with `permissions_map_file`.", + "name": "permissions_map", + "type": "object" + }, + { + "default": "", + "description": "Reference to JSON file containing permission mappings. Mutually exclusive with `permissions_map`. See `permissions_map` for more information.", "name": "permissions_map_file", "type": "string" }, diff --git a/server/testdata/integration/config/09_couper.hcl b/server/testdata/integration/config/09_couper.hcl index 3bde4d8c5..f36070bcd 100644 --- a/server/testdata/integration/config/09_couper.hcl +++ b/server/testdata/integration/config/09_couper.hcl @@ -216,7 +216,7 @@ definitions { beta_roles_map = { "r1" = ["b"] } - beta_permissions_map = { + permissions_map = { a = ["c"] b = ["e"] # from role-mapped permission c = ["d"] From 20c02c8bf8d6f2f4a37f4a95c4a0f50c8efa5452 Mon Sep 17 00:00:00 2001 From: Johannes Koch Date: Tue, 17 Jan 2023 11:04:26 +0100 Subject: [PATCH 10/14] beta_permissions_claim -> permissions_claim --- config/ac_jwt.go | 4 ++-- .../content/2.configuration/4.block/jwt.md | 16 ++++++++-------- .../content/2.configuration/5.variables.md | 2 +- server/testdata/integration/config/03_couper.hcl | 8 ++++---- server/testdata/integration/config/09_couper.hcl | 6 +++--- server/testdata/integration/config/11_couper.hcl | 2 +- .../integration/error_handler/04_couper.hcl | 2 +- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/config/ac_jwt.go b/config/ac_jwt.go index afc61436c..b95717443 100644 --- a/config/ac_jwt.go +++ b/config/ac_jwt.go @@ -39,8 +39,8 @@ type JWT struct { RolesClaim string `hcl:"beta_roles_claim,optional" docs:"Name of claim specifying the roles of the user represented by the token. The claim value must either be a string containing a space-separated list of role values or a list of string role values."` RolesMap map[string][]string `hcl:"beta_roles_map,optional" docs:"Mapping of roles to granted permissions. Non-mapped roles can be assigned with {*} to specific permissions. Mutually exclusive with {beta_roles_map_file}."` RolesMapFile string `hcl:"beta_roles_map_file,optional" docs:"Reference to JSON file containing role mappings. Mutually exclusive with {beta_roles_map}. See {beta_roles_map} for more information."` - PermissionsClaim string `hcl:"beta_permissions_claim,optional" docs:"Name of claim containing the granted permissions. The claim value must either be a string containing a space-separated list of permissions or a list of string permissions."` - PermissionsMap map[string][]string `hcl:"permissions_map,optional" docs:"Mapping of granted permissions to additional granted permissions. Maps values from {beta_permissions_claim} and those created from {beta_roles_map}. The map is called recursively. Mutually exclusive with {permissions_map_file}."` + PermissionsClaim string `hcl:"permissions_claim,optional" docs:"Name of claim containing the granted permissions. The claim value must either be a string containing a space-separated list of permissions or a list of string permissions."` + PermissionsMap map[string][]string `hcl:"permissions_map,optional" docs:"Mapping of granted permissions to additional granted permissions. Maps values from {permissions_claim} and those created from {beta_roles_map}. The map is called recursively. Mutually exclusive with {permissions_map_file}."` PermissionsMapFile string `hcl:"permissions_map_file,optional" docs:"Reference to JSON file containing permission mappings. Mutually exclusive with {permissions_map}. See {permissions_map} for more information."` SignatureAlgorithm string `hcl:"signature_algorithm,optional" docs:"Valid values: {RS256}, {RS384}, {RS512}, {HS256}, {HS384}, {HS512}, {ES256}, {ES384}, {ES512}"` SigningKey string `hcl:"signing_key,optional" docs:"Private key (in PEM format) for {RS*} and {ES*} variants. Mutually exclusive with {signing_key_file}."` diff --git a/docs/website/content/2.configuration/4.block/jwt.md b/docs/website/content/2.configuration/4.block/jwt.md index dc614c97f..0e59c21ed 100644 --- a/docs/website/content/2.configuration/4.block/jwt.md +++ b/docs/website/content/2.configuration/4.block/jwt.md @@ -20,12 +20,6 @@ values: [ "name": "backend", "type": "string" }, - { - "default": "", - "description": "Name of claim containing the granted permissions. The claim value must either be a string containing a space-separated list of permissions or a list of string permissions.", - "name": "beta_permissions_claim", - "type": "string" - }, { "default": "", "description": "Name of claim specifying the roles of the user represented by the token. The claim value must either be a string containing a space-separated list of role values or a list of string role values.", @@ -106,7 +100,13 @@ values: [ }, { "default": "", - "description": "Mapping of granted permissions to additional granted permissions. Maps values from `beta_permissions_claim` and those created from `beta_roles_map`. The map is called recursively. Mutually exclusive with `permissions_map_file`.", + "description": "Name of claim containing the granted permissions. The claim value must either be a string containing a space-separated list of permissions or a list of string permissions.", + "name": "permissions_claim", + "type": "string" + }, + { + "default": "", + "description": "Mapping of granted permissions to additional granted permissions. Maps values from `permissions_claim` and those created from `beta_roles_map`. The map is called recursively. Mutually exclusive with `permissions_map_file`.", "name": "permissions_map", "type": "object" }, @@ -165,7 +165,7 @@ Otherwise, a JSON web key set should be referenced via `jwks_url`; in this case, A JWT access control configured by this block can extract permissions from -- the value of the claim specified by `beta_permissions_claim` and +- the value of the claim specified by `permissions_claim` and - the result of mapping the value of the claim specified by `beta_roles_claim` using the `beta_roles_map`. The `jwt` block may also be referenced by the [`jwt_sign()` function](/configuration/functions), if it has a `signing_ttl` defined. For `HS*` algorithms the signing key is taken from `key`/`key_file`, for `RS*` and `ES*` algorithms, `signing_key` or `signing_key_file` have to be specified. diff --git a/docs/website/content/2.configuration/5.variables.md b/docs/website/content/2.configuration/5.variables.md index 6bf85d570..2d8db6ecf 100644 --- a/docs/website/content/2.configuration/5.variables.md +++ b/docs/website/content/2.configuration/5.variables.md @@ -53,7 +53,7 @@ defaults { | `body` | string | Request message body | | | `form_body.` | list (string) | Parameter in a `application/x-www-form-urlencoded` body | | | `json_body` | various | Access JSON decoded message body. Media type must be `application/json` or `application/*+json`. | | -| `context.granted_permissions` | list (string) | Permissions granted to the requester as yielded by access controls (see e.g. `beta_permissions_claim`, `beta_roles_claim` in the [`jwt` block](/configuration/block/jwt)). | `["perm1", "perm2"]` | +| `context.granted_permissions` | list (string) | Permissions granted to the requester as yielded by access controls (see e.g. `permissions_claim`, `beta_roles_claim` in the [`jwt` block](/configuration/block/jwt)). | `["perm1", "perm2"]` | | `context.required_permission` | string | Permission required to perform the requested operation (value of the `required_permission` attribute of [`endpoint`](#endpoint-block) (or [`api`](/configuration/block/api)) block). | | | `context..` | various | Request context containing information from the [access control](/configuration/access-control). | | | `url` | string | Request URL | `"https://www.example.com/path/to?q=val&a=1"` | diff --git a/server/testdata/integration/config/03_couper.hcl b/server/testdata/integration/config/03_couper.hcl index 8a1b9ad7c..6d5abb2f4 100644 --- a/server/testdata/integration/config/03_couper.hcl +++ b/server/testdata/integration/config/03_couper.hcl @@ -301,7 +301,7 @@ definitions { jwt "JWTToken" { signature_algorithm = "HS256" key = "y0urS3cretT08eU5edF0rC0uPerInThe3xamp1e" - beta_permissions_claim = "scope" + permissions_claim = "scope" } jwt "RSAToken" { signature_algorithm = "RS256" @@ -366,7 +366,7 @@ definitions { jwt "JWKS_scope" { jwks_url = "file:../files/jwks.json" - beta_permissions_claim = "scope" + permissions_claim = "scope" } jwt "JWKSRemote" { @@ -394,14 +394,14 @@ definitions { token_value = request.query.token[0] signature_algorithm = "HS256" key = "y0urS3cretT08eU5edF0rC0uPerInThe3xamp1e" - beta_permissions_claim = "scope" + permissions_claim = "scope" } jwt "JWT_token_value_body" { token_value = request.json_body.token signature_algorithm = "HS256" key = "y0urS3cretT08eU5edF0rC0uPerInThe3xamp1e" - beta_permissions_claim = "scope" + permissions_claim = "scope" } backend "jwks" { diff --git a/server/testdata/integration/config/09_couper.hcl b/server/testdata/integration/config/09_couper.hcl index f36070bcd..8b40de749 100644 --- a/server/testdata/integration/config/09_couper.hcl +++ b/server/testdata/integration/config/09_couper.hcl @@ -196,7 +196,7 @@ definitions { header = "authorization" signature_algorithm = "HS256" key = "asdf" - beta_permissions_claim = "scp" + permissions_claim = "scp" } jwt "roled_jwt" { header = "authorization" @@ -211,7 +211,7 @@ definitions { header = "authorization" signature_algorithm = "HS256" key = "asdf" - beta_permissions_claim = "scp" + permissions_claim = "scp" beta_roles_claim = "rl" beta_roles_map = { "r1" = ["b"] @@ -227,7 +227,7 @@ definitions { header = "authorization" signature_algorithm = "HS256" key = "asdf" - beta_permissions_claim = "scp" + permissions_claim = "scp" beta_roles_claim = "rl" beta_roles_map_file = "testdata/integration/config/roles.json" permissions_map_file = "testdata/integration/config/permissions.json" diff --git a/server/testdata/integration/config/11_couper.hcl b/server/testdata/integration/config/11_couper.hcl index 6c766798c..6bd923219 100644 --- a/server/testdata/integration/config/11_couper.hcl +++ b/server/testdata/integration/config/11_couper.hcl @@ -109,6 +109,6 @@ definitions { jwt "token" { signature_algorithm = "HS256" key = "asdf" - beta_permissions_claim = "scope" + permissions_claim = "scope" } } diff --git a/server/testdata/integration/error_handler/04_couper.hcl b/server/testdata/integration/error_handler/04_couper.hcl index 5316763b6..fb9d76365 100644 --- a/server/testdata/integration/error_handler/04_couper.hcl +++ b/server/testdata/integration/error_handler/04_couper.hcl @@ -110,6 +110,6 @@ definitions { header = "Authorization" signature_algorithm = "HS256" key = "s3cr3t" - beta_permissions_claim = "scope" + permissions_claim = "scope" } } From 9eaabd1b0332bbc2774b938c1aa426986917af76 Mon Sep 17 00:00:00 2001 From: Johannes Koch Date: Tue, 17 Jan 2023 11:11:19 +0100 Subject: [PATCH 11/14] beta_roles_map_file -> roles_map_file --- accesscontrol/jwt_test.go | 8 ++++---- config/ac_jwt.go | 4 ++-- .../website/content/2.configuration/4.block/jwt.md | 14 +++++++------- server/testdata/integration/config/09_couper.hcl | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/accesscontrol/jwt_test.go b/accesscontrol/jwt_test.go index 04be6a550..d4bd0494f 100644 --- a/accesscontrol/jwt_test.go +++ b/accesscontrol/jwt_test.go @@ -715,7 +715,7 @@ func TestJwtConfig(t *testing.T) { "configuration error: myac: jwt key: read error: configured attribute and file", }, { - "signature_algorithm, both beta_roles_map and beta_roles_map_file", + "signature_algorithm, both beta_roles_map and roles_map_file", ` server "test" {} definitions { @@ -724,14 +724,14 @@ func TestJwtConfig(t *testing.T) { header = "..." key = "..." beta_roles_map = {} - beta_roles_map_file = "testdata/map.json" + roles_map_file = "testdata/map.json" } } `, "configuration error: myac: jwt roles map: read error: configured attribute and file", }, { - "signature_algorithm, beta_roles_map_file not found", + "signature_algorithm, roles_map_file not found", ` server "test" {} definitions { @@ -739,7 +739,7 @@ func TestJwtConfig(t *testing.T) { signature_algorithm = "HS256" header = "..." key = "..." - beta_roles_map_file = "file_not_found" + roles_map_file = "file_not_found" } } `, diff --git a/config/ac_jwt.go b/config/ac_jwt.go index b95717443..99890221e 100644 --- a/config/ac_jwt.go +++ b/config/ac_jwt.go @@ -37,8 +37,8 @@ type JWT struct { Name string `hcl:"name,label"` Remain hcl.Body `hcl:",remain"` RolesClaim string `hcl:"beta_roles_claim,optional" docs:"Name of claim specifying the roles of the user represented by the token. The claim value must either be a string containing a space-separated list of role values or a list of string role values."` - RolesMap map[string][]string `hcl:"beta_roles_map,optional" docs:"Mapping of roles to granted permissions. Non-mapped roles can be assigned with {*} to specific permissions. Mutually exclusive with {beta_roles_map_file}."` - RolesMapFile string `hcl:"beta_roles_map_file,optional" docs:"Reference to JSON file containing role mappings. Mutually exclusive with {beta_roles_map}. See {beta_roles_map} for more information."` + RolesMap map[string][]string `hcl:"beta_roles_map,optional" docs:"Mapping of roles to granted permissions. Non-mapped roles can be assigned with {*} to specific permissions. Mutually exclusive with {roles_map_file}."` + RolesMapFile string `hcl:"roles_map_file,optional" docs:"Reference to JSON file containing role mappings. Mutually exclusive with {beta_roles_map}. See {beta_roles_map} for more information."` PermissionsClaim string `hcl:"permissions_claim,optional" docs:"Name of claim containing the granted permissions. The claim value must either be a string containing a space-separated list of permissions or a list of string permissions."` PermissionsMap map[string][]string `hcl:"permissions_map,optional" docs:"Mapping of granted permissions to additional granted permissions. Maps values from {permissions_claim} and those created from {beta_roles_map}. The map is called recursively. Mutually exclusive with {permissions_map_file}."` PermissionsMapFile string `hcl:"permissions_map_file,optional" docs:"Reference to JSON file containing permission mappings. Mutually exclusive with {permissions_map}. See {permissions_map} for more information."` diff --git a/docs/website/content/2.configuration/4.block/jwt.md b/docs/website/content/2.configuration/4.block/jwt.md index 0e59c21ed..db76aa8b9 100644 --- a/docs/website/content/2.configuration/4.block/jwt.md +++ b/docs/website/content/2.configuration/4.block/jwt.md @@ -28,16 +28,10 @@ values: [ }, { "default": "", - "description": "Mapping of roles to granted permissions. Non-mapped roles can be assigned with `*` to specific permissions. Mutually exclusive with `beta_roles_map_file`.", + "description": "Mapping of roles to granted permissions. Non-mapped roles can be assigned with `*` to specific permissions. Mutually exclusive with `roles_map_file`.", "name": "beta_roles_map", "type": "object" }, - { - "default": "", - "description": "Reference to JSON file containing role mappings. Mutually exclusive with `beta_roles_map`. See `beta_roles_map` for more information.", - "name": "beta_roles_map_file", - "type": "string" - }, { "default": "", "description": "Object with claims that must be given for a valid token (equals comparison with JWT payload). The claim values are evaluated per request.", @@ -122,6 +116,12 @@ values: [ "name": "required_claims", "type": "tuple (string)" }, + { + "default": "", + "description": "Reference to JSON file containing role mappings. Mutually exclusive with `beta_roles_map`. See `beta_roles_map` for more information.", + "name": "roles_map_file", + "type": "string" + }, { "default": "", "description": "Valid values: `RS256`, `RS384`, `RS512`, `HS256`, `HS384`, `HS512`, `ES256`, `ES384`, `ES512`", diff --git a/server/testdata/integration/config/09_couper.hcl b/server/testdata/integration/config/09_couper.hcl index 8b40de749..867941909 100644 --- a/server/testdata/integration/config/09_couper.hcl +++ b/server/testdata/integration/config/09_couper.hcl @@ -229,7 +229,7 @@ definitions { key = "asdf" permissions_claim = "scp" beta_roles_claim = "rl" - beta_roles_map_file = "testdata/integration/config/roles.json" + roles_map_file = "testdata/integration/config/roles.json" permissions_map_file = "testdata/integration/config/permissions.json" } } From ba83782b047cc7fd994fc0fb163a2015bde7f717 Mon Sep 17 00:00:00 2001 From: Johannes Koch Date: Tue, 17 Jan 2023 11:21:15 +0100 Subject: [PATCH 12/14] beta_roles_map -> roles_map --- accesscontrol/jwt.go | 2 +- accesscontrol/jwt_test.go | 4 ++-- config/ac_jwt.go | 6 +++--- config/configload/validate_test.go | 4 ++-- .../content/2.configuration/4.block/jwt.md | 18 +++++++++--------- .../testdata/integration/config/09_couper.hcl | 4 ++-- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/accesscontrol/jwt.go b/accesscontrol/jwt.go index 49d8354ca..c6e392f65 100644 --- a/accesscontrol/jwt.go +++ b/accesscontrol/jwt.go @@ -165,7 +165,7 @@ func newJWT(options *JWTOptions) (*JWT, error) { } if options.RolesClaim != "" && options.RolesMap == nil { - return nil, fmt.Errorf("missing beta_roles_map") + return nil, fmt.Errorf("missing roles_map") } jwtAC := &JWT{ diff --git a/accesscontrol/jwt_test.go b/accesscontrol/jwt_test.go index d4bd0494f..16cfea6e2 100644 --- a/accesscontrol/jwt_test.go +++ b/accesscontrol/jwt_test.go @@ -715,7 +715,7 @@ func TestJwtConfig(t *testing.T) { "configuration error: myac: jwt key: read error: configured attribute and file", }, { - "signature_algorithm, both beta_roles_map and roles_map_file", + "signature_algorithm, both roles_map and roles_map_file", ` server "test" {} definitions { @@ -723,7 +723,7 @@ func TestJwtConfig(t *testing.T) { signature_algorithm = "HS256" header = "..." key = "..." - beta_roles_map = {} + roles_map = {} roles_map_file = "testdata/map.json" } } diff --git a/config/ac_jwt.go b/config/ac_jwt.go index 99890221e..dcfadf85e 100644 --- a/config/ac_jwt.go +++ b/config/ac_jwt.go @@ -37,10 +37,10 @@ type JWT struct { Name string `hcl:"name,label"` Remain hcl.Body `hcl:",remain"` RolesClaim string `hcl:"beta_roles_claim,optional" docs:"Name of claim specifying the roles of the user represented by the token. The claim value must either be a string containing a space-separated list of role values or a list of string role values."` - RolesMap map[string][]string `hcl:"beta_roles_map,optional" docs:"Mapping of roles to granted permissions. Non-mapped roles can be assigned with {*} to specific permissions. Mutually exclusive with {roles_map_file}."` - RolesMapFile string `hcl:"roles_map_file,optional" docs:"Reference to JSON file containing role mappings. Mutually exclusive with {beta_roles_map}. See {beta_roles_map} for more information."` + RolesMap map[string][]string `hcl:"roles_map,optional" docs:"Mapping of roles to granted permissions. Non-mapped roles can be assigned with {*} to specific permissions. Mutually exclusive with {roles_map_file}."` + RolesMapFile string `hcl:"roles_map_file,optional" docs:"Reference to JSON file containing role mappings. Mutually exclusive with {roles_map}. See {roles_map} for more information."` PermissionsClaim string `hcl:"permissions_claim,optional" docs:"Name of claim containing the granted permissions. The claim value must either be a string containing a space-separated list of permissions or a list of string permissions."` - PermissionsMap map[string][]string `hcl:"permissions_map,optional" docs:"Mapping of granted permissions to additional granted permissions. Maps values from {permissions_claim} and those created from {beta_roles_map}. The map is called recursively. Mutually exclusive with {permissions_map_file}."` + PermissionsMap map[string][]string `hcl:"permissions_map,optional" docs:"Mapping of granted permissions to additional granted permissions. Maps values from {permissions_claim} and those created from {roles_map}. The map is called recursively. Mutually exclusive with {permissions_map_file}."` PermissionsMapFile string `hcl:"permissions_map_file,optional" docs:"Reference to JSON file containing permission mappings. Mutually exclusive with {permissions_map}. See {permissions_map} for more information."` SignatureAlgorithm string `hcl:"signature_algorithm,optional" docs:"Valid values: {RS256}, {RS384}, {RS512}, {HS256}, {HS384}, {HS512}, {ES256}, {ES384}, {ES512}"` SigningKey string `hcl:"signing_key,optional" docs:"Private key (in PEM format) for {RS*} and {ES*} variants. Mutually exclusive with {signing_key_file}."` diff --git a/config/configload/validate_test.go b/config/configload/validate_test.go index 5e1329a09..1030dcf2e 100644 --- a/config/configload/validate_test.go +++ b/config/configload/validate_test.go @@ -1253,13 +1253,13 @@ func TestAttributeObjectKeys(t *testing.T) { "", }, { - "beta_roles_map", + "roles_map", `server {} definitions { jwt "a" { signature_algorithm = "HS256" key = "asdf" - beta_roles_map = { + roles_map = { a = [] A = [] } diff --git a/docs/website/content/2.configuration/4.block/jwt.md b/docs/website/content/2.configuration/4.block/jwt.md index db76aa8b9..dfc9a0b7c 100644 --- a/docs/website/content/2.configuration/4.block/jwt.md +++ b/docs/website/content/2.configuration/4.block/jwt.md @@ -26,12 +26,6 @@ values: [ "name": "beta_roles_claim", "type": "string" }, - { - "default": "", - "description": "Mapping of roles to granted permissions. Non-mapped roles can be assigned with `*` to specific permissions. Mutually exclusive with `roles_map_file`.", - "name": "beta_roles_map", - "type": "object" - }, { "default": "", "description": "Object with claims that must be given for a valid token (equals comparison with JWT payload). The claim values are evaluated per request.", @@ -100,7 +94,7 @@ values: [ }, { "default": "", - "description": "Mapping of granted permissions to additional granted permissions. Maps values from `permissions_claim` and those created from `beta_roles_map`. The map is called recursively. Mutually exclusive with `permissions_map_file`.", + "description": "Mapping of granted permissions to additional granted permissions. Maps values from `permissions_claim` and those created from `roles_map`. The map is called recursively. Mutually exclusive with `permissions_map_file`.", "name": "permissions_map", "type": "object" }, @@ -118,7 +112,13 @@ values: [ }, { "default": "", - "description": "Reference to JSON file containing role mappings. Mutually exclusive with `beta_roles_map`. See `beta_roles_map` for more information.", + "description": "Mapping of roles to granted permissions. Non-mapped roles can be assigned with `*` to specific permissions. Mutually exclusive with `roles_map_file`.", + "name": "roles_map", + "type": "object" + }, + { + "default": "", + "description": "Reference to JSON file containing role mappings. Mutually exclusive with `roles_map`. See `roles_map` for more information.", "name": "roles_map_file", "type": "string" }, @@ -166,7 +166,7 @@ Otherwise, a JSON web key set should be referenced via `jwks_url`; in this case, A JWT access control configured by this block can extract permissions from - the value of the claim specified by `permissions_claim` and -- the result of mapping the value of the claim specified by `beta_roles_claim` using the `beta_roles_map`. +- the result of mapping the value of the claim specified by `beta_roles_claim` using the `roles_map`. The `jwt` block may also be referenced by the [`jwt_sign()` function](/configuration/functions), if it has a `signing_ttl` defined. For `HS*` algorithms the signing key is taken from `key`/`key_file`, for `RS*` and `ES*` algorithms, `signing_key` or `signing_key_file` have to be specified. diff --git a/server/testdata/integration/config/09_couper.hcl b/server/testdata/integration/config/09_couper.hcl index 867941909..e198639cc 100644 --- a/server/testdata/integration/config/09_couper.hcl +++ b/server/testdata/integration/config/09_couper.hcl @@ -203,7 +203,7 @@ definitions { signature_algorithm = "HS256" key = "asdf" beta_roles_claim = "rl" - beta_roles_map = { + roles_map = { "r1" = ["a", "b"] } } @@ -213,7 +213,7 @@ definitions { key = "asdf" permissions_claim = "scp" beta_roles_claim = "rl" - beta_roles_map = { + roles_map = { "r1" = ["b"] } permissions_map = { From 0f9be967987ab70997246ca3249e6cfd046321d1 Mon Sep 17 00:00:00 2001 From: Johannes Koch Date: Tue, 17 Jan 2023 11:27:47 +0100 Subject: [PATCH 13/14] beta_roles_claim -> roles_claim --- config/ac_jwt.go | 2 +- .../website/content/2.configuration/4.block/jwt.md | 14 +++++++------- .../website/content/2.configuration/5.variables.md | 2 +- server/testdata/integration/config/09_couper.hcl | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/config/ac_jwt.go b/config/ac_jwt.go index dcfadf85e..c7fb43ca5 100644 --- a/config/ac_jwt.go +++ b/config/ac_jwt.go @@ -36,7 +36,7 @@ type JWT struct { KeyFile string `hcl:"key_file,optional" docs:"Reference to file containing verification key. Mutually exclusive with {key}. See {key} for more information."` Name string `hcl:"name,label"` Remain hcl.Body `hcl:",remain"` - RolesClaim string `hcl:"beta_roles_claim,optional" docs:"Name of claim specifying the roles of the user represented by the token. The claim value must either be a string containing a space-separated list of role values or a list of string role values."` + RolesClaim string `hcl:"roles_claim,optional" docs:"Name of claim specifying the roles of the user represented by the token. The claim value must either be a string containing a space-separated list of role values or a list of string role values."` RolesMap map[string][]string `hcl:"roles_map,optional" docs:"Mapping of roles to granted permissions. Non-mapped roles can be assigned with {*} to specific permissions. Mutually exclusive with {roles_map_file}."` RolesMapFile string `hcl:"roles_map_file,optional" docs:"Reference to JSON file containing role mappings. Mutually exclusive with {roles_map}. See {roles_map} for more information."` PermissionsClaim string `hcl:"permissions_claim,optional" docs:"Name of claim containing the granted permissions. The claim value must either be a string containing a space-separated list of permissions or a list of string permissions."` diff --git a/docs/website/content/2.configuration/4.block/jwt.md b/docs/website/content/2.configuration/4.block/jwt.md index dfc9a0b7c..5a9aac6a3 100644 --- a/docs/website/content/2.configuration/4.block/jwt.md +++ b/docs/website/content/2.configuration/4.block/jwt.md @@ -20,12 +20,6 @@ values: [ "name": "backend", "type": "string" }, - { - "default": "", - "description": "Name of claim specifying the roles of the user represented by the token. The claim value must either be a string containing a space-separated list of role values or a list of string role values.", - "name": "beta_roles_claim", - "type": "string" - }, { "default": "", "description": "Object with claims that must be given for a valid token (equals comparison with JWT payload). The claim values are evaluated per request.", @@ -110,6 +104,12 @@ values: [ "name": "required_claims", "type": "tuple (string)" }, + { + "default": "", + "description": "Name of claim specifying the roles of the user represented by the token. The claim value must either be a string containing a space-separated list of role values or a list of string role values.", + "name": "roles_claim", + "type": "string" + }, { "default": "", "description": "Mapping of roles to granted permissions. Non-mapped roles can be assigned with `*` to specific permissions. Mutually exclusive with `roles_map_file`.", @@ -166,7 +166,7 @@ Otherwise, a JSON web key set should be referenced via `jwks_url`; in this case, A JWT access control configured by this block can extract permissions from - the value of the claim specified by `permissions_claim` and -- the result of mapping the value of the claim specified by `beta_roles_claim` using the `roles_map`. +- the result of mapping the value of the claim specified by `roles_claim` using the `roles_map`. The `jwt` block may also be referenced by the [`jwt_sign()` function](/configuration/functions), if it has a `signing_ttl` defined. For `HS*` algorithms the signing key is taken from `key`/`key_file`, for `RS*` and `ES*` algorithms, `signing_key` or `signing_key_file` have to be specified. diff --git a/docs/website/content/2.configuration/5.variables.md b/docs/website/content/2.configuration/5.variables.md index 2d8db6ecf..1a0af6481 100644 --- a/docs/website/content/2.configuration/5.variables.md +++ b/docs/website/content/2.configuration/5.variables.md @@ -53,7 +53,7 @@ defaults { | `body` | string | Request message body | | | `form_body.` | list (string) | Parameter in a `application/x-www-form-urlencoded` body | | | `json_body` | various | Access JSON decoded message body. Media type must be `application/json` or `application/*+json`. | | -| `context.granted_permissions` | list (string) | Permissions granted to the requester as yielded by access controls (see e.g. `permissions_claim`, `beta_roles_claim` in the [`jwt` block](/configuration/block/jwt)). | `["perm1", "perm2"]` | +| `context.granted_permissions` | list (string) | Permissions granted to the requester as yielded by access controls (see e.g. `permissions_claim`, `roles_claim` in the [`jwt` block](/configuration/block/jwt)). | `["perm1", "perm2"]` | | `context.required_permission` | string | Permission required to perform the requested operation (value of the `required_permission` attribute of [`endpoint`](#endpoint-block) (or [`api`](/configuration/block/api)) block). | | | `context..` | various | Request context containing information from the [access control](/configuration/access-control). | | | `url` | string | Request URL | `"https://www.example.com/path/to?q=val&a=1"` | diff --git a/server/testdata/integration/config/09_couper.hcl b/server/testdata/integration/config/09_couper.hcl index e198639cc..c0300ca05 100644 --- a/server/testdata/integration/config/09_couper.hcl +++ b/server/testdata/integration/config/09_couper.hcl @@ -202,7 +202,7 @@ definitions { header = "authorization" signature_algorithm = "HS256" key = "asdf" - beta_roles_claim = "rl" + roles_claim = "rl" roles_map = { "r1" = ["a", "b"] } @@ -212,7 +212,7 @@ definitions { signature_algorithm = "HS256" key = "asdf" permissions_claim = "scp" - beta_roles_claim = "rl" + roles_claim = "rl" roles_map = { "r1" = ["b"] } @@ -228,7 +228,7 @@ definitions { signature_algorithm = "HS256" key = "asdf" permissions_claim = "scp" - beta_roles_claim = "rl" + roles_claim = "rl" roles_map_file = "testdata/integration/config/roles.json" permissions_map_file = "testdata/integration/config/permissions.json" } From 063d026f70b0a5d102912e78f57496662d2c6585 Mon Sep 17 00:00:00 2001 From: Johannes Koch Date: Thu, 26 Jan 2023 13:44:56 +0100 Subject: [PATCH 14/14] changelog entry --- CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cd0e88fe..8165d4799 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,10 +12,15 @@ Unreleased changes are available as `avenga/couper:edge` container. * Use nested `jwt_signing_profile` block in [`oauth2` block](https://docs.couper.io/configuration/block/oauth2) for `grant_type` `"urn:ietf:params:oauth:grant-type:jwt-bearer"` in absence of `assertion` attribute ([#619](https://github.com/avenga/couper/pull/619)) * Improved the way an SPA `bootstrap_file` gets cached and served in combination with `bootstrap_data` ([#656](https://github.com/avenga/couper/pull/656)) * Harmonized and improved logged error information for references to undefined blocks ([#651](https://github.com/avenga/couper/pull/651)) + * Unbeta permission features: ([#673](https://github.com/avenga/couper/pull/673)) + * `beta_required_permission` attribute for [`api`](https://docs.couper.io/configuration/block/api#attribute-beta_required_permission) and [`endpoint`](https://docs.couper.io/configuration/block/endpoint#attribute-beta_required_permission) blocks, + * `beta_granted_permissions` and `beta_required_permission` [request context variables](https://docs.couper.io/configuration/variables#request), + * `beta_insufficient_permissions` [error type](https://docs.couper.io/configuration/error-handling/#api-error-types), + * `beta_permissions_claim`, `beta_permissions_map`, `beta_permissions_map_file`, `beta_roles_claim`, `beta_roles_map` and `beta_roles_map_file` attributes for [`jwt` block](https://docs.couper.io/configuration/block/jwt#attributes). * **Fixed** - * Loop with evaluation error in [`custom_log_fields`](https://docs.couper.io/observation/logging#custom-logging) if log level is `"debug"` ([#659](https://github.com/avenga/couper/pull/659)) * Use of [backend-related variables](https://docs.couper.io/configuration/variables#backend) in [`custom_log_fields`](https://docs.couper.io/observation/logging#custom-logging) within a [`backend` block](https://docs.couper.io/configuration/block/backend) ([#658](https://github.com/avenga/couper/pull/658)) + * Loop with evaluation error in [`custom_log_fields`](https://docs.couper.io/observation/logging#custom-logging) if log level is `"debug"` ([#659](https://github.com/avenga/couper/pull/659)) ---