From b2d35d88ec6d9f652e3926cbdd083b03162da9c2 Mon Sep 17 00:00:00 2001 From: James Elliott Date: Fri, 1 Apr 2022 21:53:10 +1100 Subject: [PATCH] feat(configuration): allow rfc4918 http verbs in acl (#2988) This allows the HTTP Method verbs from RFC4918 to be used. See https://datatracker.ietf.org/doc/html/rfc4918 for more information. --- api/openapi.yml | 18 +++++++++++++++++- docs/configuration/access-control.md | 12 ++++++++++-- .../configuration/validator/access_control.go | 4 ++-- .../validator/access_control_test.go | 2 +- internal/configuration/validator/const.go | 6 +++++- 5 files changed, 35 insertions(+), 7 deletions(-) diff --git a/api/openapi.yml b/api/openapi.yml index 74f4dad1..35136362 100644 --- a/api/openapi.yml +++ b/api/openapi.yml @@ -637,7 +637,23 @@ components: explode: true schema: type: string - enum: ["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "TRACE", "CONNECT", "OPTIONS"] + enum: + - "GET" + - "HEAD" + - "POST" + - "PUT" + - "PATCH" + - "DELETE" + - "TRACE" + - "CONNECT" + - "OPTIONS" + - "COPY" + - "LOCK" + - "MKCOL" + - "MOVE" + - "PROPFIND" + - "PROPPATCH" + - "UNLOCK" authParam: name: auth in: query diff --git a/docs/configuration/access-control.md b/docs/configuration/access-control.md index 158d2761..7c90395b 100644 --- a/docs/configuration/access-control.md +++ b/docs/configuration/access-control.md @@ -271,8 +271,16 @@ access_control: - OPTIONS ``` -The valid request methods are: OPTIONS, HEAD, GET, POST, PUT, PATCH, DELETE, TRACE, CONNECT. Additional information -about HTTP request methods can be found on the [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods). +The accepted and valid methods for this configuration option are those specified in well known RFC's. The RFC's and the +relevant methods are listed in this table: + +| RFC | Methods | Additional Documentation | +|:--------------------------------------------------------:|:-----------------------------------------------------:|:----------------------------------------------------------------:| +| [RFC7231](https://datatracker.ietf.org/doc/html/rfc7231) | GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE | [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) | +| [RFC5789](https://datatracker.ietf.org/doc/html/rfc5789) | PATCH | [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) | +| [RFC4918](https://datatracker.ietf.org/doc/html/rfc4918) | PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK | | + + ### networks
diff --git a/internal/configuration/validator/access_control.go b/internal/configuration/validator/access_control.go index 1b70be0d..ec89b395 100644 --- a/internal/configuration/validator/access_control.go +++ b/internal/configuration/validator/access_control.go @@ -147,8 +147,8 @@ func validateSubjects(rulePosition int, rule schema.ACLRule, validator *schema.S func validateMethods(rulePosition int, rule schema.ACLRule, validator *schema.StructValidator) { for _, method := range rule.Methods { - if !utils.IsStringInSliceFold(method, validACLRuleMethods) { - validator.Push(fmt.Errorf(errFmtAccessControlRuleMethodInvalid, ruleDescriptor(rulePosition, rule), method, strings.Join(validACLRuleMethods, "', '"))) + if !utils.IsStringInSliceFold(method, validACLHTTPMethodVerbs) { + validator.Push(fmt.Errorf(errFmtAccessControlRuleMethodInvalid, ruleDescriptor(rulePosition, rule), method, strings.Join(validACLHTTPMethodVerbs, "', '"))) } } } diff --git a/internal/configuration/validator/access_control_test.go b/internal/configuration/validator/access_control_test.go index 05c95e4e..7e66864b 100644 --- a/internal/configuration/validator/access_control_test.go +++ b/internal/configuration/validator/access_control_test.go @@ -152,7 +152,7 @@ func (suite *AccessControl) TestShouldRaiseErrorInvalidMethod() { suite.Assert().False(suite.validator.HasWarnings()) suite.Require().Len(suite.validator.Errors(), 1) - suite.Assert().EqualError(suite.validator.Errors()[0], "access control: rule #1 (domain 'public.example.com'): 'methods' option 'HOP' is invalid: must be one of 'GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE', 'TRACE', 'CONNECT', 'OPTIONS'") + suite.Assert().EqualError(suite.validator.Errors()[0], "access control: rule #1 (domain 'public.example.com'): 'methods' option 'HOP' is invalid: must be one of 'GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE', 'TRACE', 'CONNECT', 'OPTIONS', 'COPY', 'LOCK', 'MKCOL', 'MOVE', 'PROPFIND', 'PROPPATCH', 'UNLOCK'") } func (suite *AccessControl) TestShouldRaiseErrorInvalidResource() { diff --git a/internal/configuration/validator/const.go b/internal/configuration/validator/const.go index 0b3a410c..95ba84f9 100644 --- a/internal/configuration/validator/const.go +++ b/internal/configuration/validator/const.go @@ -256,7 +256,11 @@ var validLoLevels = []string{"trace", "debug", "info", "warn", "error"} var validWebauthnConveyancePreferences = []string{string(protocol.PreferNoAttestation), string(protocol.PreferIndirectAttestation), string(protocol.PreferDirectAttestation)} var validWebauthnUserVerificationRequirement = []string{string(protocol.VerificationDiscouraged), string(protocol.VerificationPreferred), string(protocol.VerificationRequired)} -var validACLRuleMethods = []string{"GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "TRACE", "CONNECT", "OPTIONS"} +var validRFC7231HTTPMethodVerbs = []string{"GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "TRACE", "CONNECT", "OPTIONS"} +var validRFC4918HTTPMethodVerbs = []string{"COPY", "LOCK", "MKCOL", "MOVE", "PROPFIND", "PROPPATCH", "UNLOCK"} + +var validACLHTTPMethodVerbs = append(validRFC7231HTTPMethodVerbs, validRFC4918HTTPMethodVerbs...) + var validACLRulePolicies = []string{policyBypass, policyOneFactor, policyTwoFactor, policyDeny} var validOIDCScopes = []string{oidc.ScopeOpenID, oidc.ScopeEmail, oidc.ScopeProfile, oidc.ScopeGroups, "offline_access"}