Skip to content

Commit

Permalink
refactor: utilize constants
Browse files Browse the repository at this point in the history
  • Loading branch information
james-d-elliott committed Dec 21, 2023
1 parent 6584d34 commit 00facf7
Show file tree
Hide file tree
Showing 58 changed files with 659 additions and 507 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ following list of differences:
<sup>[commit](https://github.com/authelia/oauth2-provider/commit/2314625eb1f21987a9199fb1cdf6da6cee4df965)</sup>
- [x] RFC9068 must condition ignored
<sup>[commit](https://github.com/authelia/oauth2-provider/commit/f4652d60c850d167da00e2d2fe9096776eff9465)</sup>
- [ ] Arguments are treated as case-insensitive
- Refresh Flow:
- [x] Requested scope ignored
- [x] Original request id not set early enough
Expand Down
5 changes: 3 additions & 2 deletions access_request_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net/http"
"strings"

"authelia.com/provider/oauth2/internal/consts"
"github.com/pkg/errors"

"authelia.com/provider/oauth2/i18n"
Expand Down Expand Up @@ -59,9 +60,9 @@ func (f *Fosite) NewAccessRequest(ctx context.Context, r *http.Request, session
return accessRequest, errors.New("Session must not be nil")
}

accessRequest.SetRequestedScopes(RemoveEmpty(strings.Split(r.PostForm.Get("scope"), " ")))
accessRequest.SetRequestedScopes(RemoveEmpty(strings.Split(r.PostForm.Get(consts.FormParameterScope), " ")))
accessRequest.SetRequestedAudience(GetAudiences(r.PostForm))
accessRequest.GrantTypes = RemoveEmpty(strings.Split(r.PostForm.Get("grant_type"), " "))
accessRequest.GrantTypes = RemoveEmpty(strings.Split(r.PostForm.Get(consts.FormParameterGrantType), " "))
if len(accessRequest.GrantTypes) < 1 {
return accessRequest, errorsx.WithStack(ErrInvalidRequest.WithHint("Request parameter 'grant_type' is missing"))
}
Expand Down
4 changes: 3 additions & 1 deletion audience_strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"net/url"
"strings"

"authelia.com/provider/oauth2/internal/consts"
"authelia.com/provider/oauth2/internal/errorsx"
)

Expand Down Expand Up @@ -82,7 +83,7 @@ func ExactAudienceMatchingStrategy(haystack []string, needle []string) error {
// more than once (and thus why we use space-delimited value). This function tries to satisfy both.
// If "audience" form parameter is repeated, we do not split the value by space.
func GetAudiences(form url.Values) []string {
audiences := form["audience"]
audiences := form[consts.FormParameterAudience]
if len(audiences) > 1 {
return RemoveEmpty(audiences)
} else if len(audiences) == 1 {
Expand All @@ -100,5 +101,6 @@ func (f *Fosite) validateAuthorizeAudience(ctx context.Context, r *http.Request,
}

request.SetRequestedAudience(audience)

return nil
}
4 changes: 3 additions & 1 deletion authorize_error.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"encoding/json"
"fmt"
"net/http"

"authelia.com/provider/oauth2/internal/consts"
)

func (f *Fosite) WriteAuthorizeError(ctx context.Context, rw http.ResponseWriter, ar AuthorizeRequester, err error) {
Expand Down Expand Up @@ -45,7 +47,7 @@ func (f *Fosite) WriteAuthorizeError(ctx context.Context, rw http.ResponseWriter
redirectURI.Fragment = ""

errors := rfcerr.ToValues()
errors.Set("state", ar.GetState())
errors.Set(consts.FormParameterState, ar.GetState())

var redirectURIString string
if ar.GetResponseMode() == ResponseModeFormPost {
Expand Down
53 changes: 27 additions & 26 deletions authorize_request_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"net/http"
"strings"

"authelia.com/provider/oauth2/internal/consts"
"github.com/go-jose/go-jose/v3"
"github.com/pkg/errors"

Expand All @@ -33,19 +34,19 @@ func (f *Fosite) authorizeRequestParametersFromOpenIDConnectRequest(ctx context.
// Even if a scope parameter is present in the Request Object value, a scope parameter MUST always be passed using
// the OAuth 2.0 request syntax containing the openid scope value to indicate to the underlying OAuth 2.0 logic that this is an OpenID Connect request.
// Source: http://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth
if !scope.Has("openid") {
if !scope.Has(consts.ScopeOpenID) {
return nil
}

if len(request.Form.Get("request")+request.Form.Get("request_uri")) == 0 {
if len(request.Form.Get(consts.FormParameterRequest)+request.Form.Get(consts.FormParameterRequestURI)) == 0 {
return nil
} else if len(request.Form.Get("request")) > 0 && len(request.Form.Get("request_uri")) > 0 {
} else if len(request.Form.Get(consts.FormParameterRequest)) > 0 && len(request.Form.Get(consts.FormParameterRequestURI)) > 0 {
return errorsx.WithStack(ErrInvalidRequest.WithHint("OpenID Connect parameters 'request' and 'request_uri' were both given, but you can use at most one."))
}

oidcClient, ok := request.Client.(OpenIDConnectClient)
if !ok {
if len(request.Form.Get("request_uri")) > 0 {
if len(request.Form.Get(consts.FormParameterRequestURI)) > 0 {
return errorsx.WithStack(ErrRequestURINotSupported.WithHint("OpenID Connect 'request_uri' context was given, but the OAuth 2.0 Client does not implement advanced OpenID Connect capabilities."))
}
return errorsx.WithStack(ErrRequestNotSupported.WithHint("OpenID Connect 'request' context was given, but the OAuth 2.0 Client does not implement advanced OpenID Connect capabilities."))
Expand All @@ -55,8 +56,8 @@ func (f *Fosite) authorizeRequestParametersFromOpenIDConnectRequest(ctx context.
return errorsx.WithStack(ErrInvalidRequest.WithHint("OpenID Connect 'request' or 'request_uri' context was given, but the OAuth 2.0 Client does not have any JSON Web Keys registered."))
}

assertion := request.Form.Get("request")
if location := request.Form.Get("request_uri"); len(location) > 0 {
assertion := request.Form.Get(consts.FormParameterRequest)
if location := request.Form.Get(consts.FormParameterRequestURI); len(location) > 0 {
if !stringslice.Has(oidcClient.GetRequestURIs(), location) {
return errorsx.WithStack(ErrInvalidRequestURI.WithHintf("Request URI '%s' is not whitelisted by the OAuth 2.0 Client.", location))
}
Expand Down Expand Up @@ -86,8 +87,8 @@ func (f *Fosite) authorizeRequestParametersFromOpenIDConnectRequest(ctx context.
// if not signed with this algorithm. Request Objects are described in Section 6.1 of OpenID Connect Core 1.0 [OpenID.Core]. This algorithm MUST
// be used both when the Request Object is passed by value (using the request parameter) and when it is passed by reference (using the request_uri parameter).
// Servers SHOULD support RS256. The value none MAY be used. The default, if omitted, is that any algorithm supported by the OP and the RP MAY be used.
if oidcClient.GetRequestObjectSigningAlgorithm() != "" && oidcClient.GetRequestObjectSigningAlgorithm() != fmt.Sprintf("%s", t.Header["alg"]) {
return nil, errorsx.WithStack(ErrInvalidRequestObject.WithHintf("The request object uses signing algorithm '%s', but the requested OAuth 2.0 Client enforces signing algorithm '%s'.", t.Header["alg"], oidcClient.GetRequestObjectSigningAlgorithm()))
if oidcClient.GetRequestObjectSigningAlgorithm() != "" && oidcClient.GetRequestObjectSigningAlgorithm() != fmt.Sprintf("%s", t.Header[consts.JSONWebTokenHeaderAlgorithm]) {
return nil, errorsx.WithStack(ErrInvalidRequestObject.WithHintf("The request object uses signing algorithm '%s', but the requested OAuth 2.0 Client enforces signing algorithm '%s'.", t.Header[consts.JSONWebTokenHeaderAlgorithm], oidcClient.GetRequestObjectSigningAlgorithm()))
}

if t.Method == jwt.SigningMethodNone {
Expand Down Expand Up @@ -137,29 +138,29 @@ func (f *Fosite) authorizeRequestParametersFromOpenIDConnectRequest(ctx context.
claims := token.Claims
// Reject the request if the "request_uri" authorization request
// parameter is provided.
if requestURI, _ := claims["request_uri"].(string); isPARRequest && requestURI != "" {
if requestURI, _ := claims[consts.FormParameterRequestURI].(string); isPARRequest && requestURI != "" {
return errorsx.WithStack(ErrInvalidRequestObject.WithHint("Pushed Authorization Requests can not contain the 'request_uri' parameter."))
}

for k, v := range claims {
request.Form.Set(k, fmt.Sprintf("%s", v))
}

claimScope := RemoveEmpty(strings.Split(request.Form.Get("scope"), " "))
claimScope := RemoveEmpty(strings.Split(request.Form.Get(consts.FormParameterScope), " "))
for _, s := range scope {
if !stringslice.Has(claimScope, s) {
claimScope = append(claimScope, s)
}
}

request.State = request.Form.Get("state")
request.Form.Set("scope", strings.Join(claimScope, " "))
request.State = request.Form.Get(consts.FormParameterState)
request.Form.Set(consts.FormParameterScope, strings.Join(claimScope, " "))
return nil
}

func (f *Fosite) validateAuthorizeRedirectURI(_ *http.Request, request *AuthorizeRequest) error {
// Fetch redirect URI from request
rawRedirURI := request.Form.Get("redirect_uri")
rawRedirURI := request.Form.Get(consts.FormParameterRedirectURI)

// This ensures that the 'redirect_uri' parameter is present for OpenID Connect 1.0 authorization requests as per:
//
Expand All @@ -168,7 +169,7 @@ func (f *Fosite) validateAuthorizeRedirectURI(_ *http.Request, request *Authoriz
// Hybrid Flow - https://openid.net/specs/openid-connect-core-1_0.html#HybridAuthRequest
//
// Note: as per the Hybrid Flow documentation the Hybrid Flow has the same requirements as the Authorization Code Flow.
if len(rawRedirURI) == 0 && request.GetRequestedScopes().Has("openid") {
if len(rawRedirURI) == 0 && request.GetRequestedScopes().Has(consts.ScopeOpenID) {
return errorsx.WithStack(ErrInvalidRequest.WithHint("The 'redirect_uri' parameter is required when using OpenID Connect 1.0."))
}

Expand All @@ -184,7 +185,7 @@ func (f *Fosite) validateAuthorizeRedirectURI(_ *http.Request, request *Authoriz
}

func (f *Fosite) parseAuthorizeScope(_ *http.Request, request *AuthorizeRequest) error {
request.SetRequestedScopes(RemoveEmpty(strings.Split(request.Form.Get("scope"), " ")))
request.SetRequestedScopes(RemoveEmpty(strings.Split(request.Form.Get(consts.FormParameterScope), " ")))

return nil
}
Expand All @@ -205,7 +206,7 @@ func (f *Fosite) validateResponseTypes(r *http.Request, request *AuthorizeReques
// values, where the order of values does not matter (e.g., response
// type "a b" is the same as "b a"). The meaning of such composite
// response types is defined by their respective specifications.
responseTypes := RemoveEmpty(strings.Split(r.Form.Get("response_type"), " "))
responseTypes := RemoveEmpty(strings.Split(r.Form.Get(consts.FormParameterResponseType), " "))
if len(responseTypes) == 0 {
return errorsx.WithStack(ErrUnsupportedResponseType.WithHint("`The request is missing the 'response_type' parameter."))
}
Expand All @@ -227,7 +228,7 @@ func (f *Fosite) validateResponseTypes(r *http.Request, request *AuthorizeReques
}

func (f *Fosite) ParseResponseMode(ctx context.Context, r *http.Request, request *AuthorizeRequest) error {
switch responseMode := r.Form.Get("response_mode"); responseMode {
switch responseMode := r.Form.Get(consts.FormParameterResponseMode); responseMode {
case string(ResponseModeDefault):
request.ResponseMode = ResponseModeDefault
case string(ResponseModeFragment):
Expand Down Expand Up @@ -280,13 +281,13 @@ func (f *Fosite) authorizeRequestFromPAR(ctx context.Context, r *http.Request, r
return false, nil
}

requestURI := r.Form.Get("request_uri")
requestURI := r.Form.Get(consts.FormParameterRequestURI)
if requestURI == "" || !strings.HasPrefix(requestURI, configProvider.GetPushedAuthorizeRequestURIPrefix(ctx)) {
// nothing to do here
return false, nil
}

clientID := r.Form.Get("client_id")
clientID := r.Form.Get(consts.FormParameterClientID)

storage, ok := f.Store.(PARStorage)
if !ok {
Expand All @@ -307,7 +308,7 @@ func (f *Fosite) authorizeRequestFromPAR(ctx context.Context, r *http.Request, r
request.State = parRequest.GetState()
request.ResponseMode = parRequest.GetResponseMode()

if err := storage.DeletePARSession(ctx, requestURI); err != nil {
if err = storage.DeletePARSession(ctx, requestURI); err != nil {
return false, errorsx.WithStack(ErrServerError.WithWrap(err).WithDebug(err.Error()))
}

Expand Down Expand Up @@ -336,7 +337,7 @@ func (f *Fosite) newAuthorizeRequest(ctx context.Context, r *http.Request, isPAR
request.Form = r.Form

// Save state to the request to be returned in error conditions (https://github.com/ory/hydra/issues/1642)
request.State = request.Form.Get("state")
request.State = request.Form.Get(consts.FormParameterState)

// Check if this is a continuation from a pushed authorization request
if !isPARRequest {
Expand All @@ -350,7 +351,7 @@ func (f *Fosite) newAuthorizeRequest(ctx context.Context, r *http.Request, isPAR
}
}

client, err := f.Store.GetClient(ctx, request.GetRequestForm().Get("client_id"))
client, err := f.Store.GetClient(ctx, request.GetRequestForm().Get(consts.FormParameterClientID))
if err != nil {
return request, errorsx.WithStack(ErrInvalidClient.WithHint("The requested OAuth 2.0 Client does not exist.").WithWrap(err).WithDebug(err.Error()))
}
Expand All @@ -361,13 +362,13 @@ func (f *Fosite) newAuthorizeRequest(ctx context.Context, r *http.Request, isPAR
//
// All other parse methods should come afterwards so that we ensure that the data is taken
// from the request_object if set.
if err := f.authorizeRequestParametersFromOpenIDConnectRequest(ctx, request, isPARRequest); err != nil {
if err = f.authorizeRequestParametersFromOpenIDConnectRequest(ctx, request, isPARRequest); err != nil {
return request, err
}

// The request context is now fully available and we can start processing the individual
// fields.
if err := f.ParseResponseMode(ctx, r, request); err != nil {
if err = f.ParseResponseMode(ctx, r, request); err != nil {
return request, err
}

Expand All @@ -387,7 +388,7 @@ func (f *Fosite) newAuthorizeRequest(ctx context.Context, r *http.Request, isPAR
return request, err
}

if len(request.Form.Get("registration")) > 0 {
if len(request.Form.Get(consts.FormParameterRegistration)) > 0 {
return request, errorsx.WithStack(ErrRegistrationNotSupported)
}

Expand All @@ -402,7 +403,7 @@ func (f *Fosite) newAuthorizeRequest(ctx context.Context, r *http.Request, isPAR
// A fallback handler to set the default response mode in cases where we can not reach the Authorize Handlers
// but still need the e.g. correct error response mode.
if request.GetResponseMode() == ResponseModeDefault {
if request.ResponseTypes.ExactOne("code") {
if request.ResponseTypes.ExactOne(consts.ResponseTypeAuthorizationCodeFlow) {
request.SetDefaultResponseMode(ResponseModeQuery)
} else {
// If the response type is not `code` it is an implicit/hybrid (fragment) response mode.
Expand Down
Loading

0 comments on commit 00facf7

Please sign in to comment.