Merge pull request #1949 from flant/use-constants-for-errors
Use constants to form oauth2 error responses
This commit is contained in:
commit
a55de6c991
2 changed files with 42 additions and 14 deletions
|
@ -485,13 +485,13 @@ func (s *Server) parseAuthorizationRequest(r *http.Request) (*storage.AuthReques
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !hasOpenIDScope {
|
if !hasOpenIDScope {
|
||||||
return nil, newErr("invalid_scope", `Missing required scope(s) ["openid"].`)
|
return nil, newErr(errInvalidScope, `Missing required scope(s) ["openid"].`)
|
||||||
}
|
}
|
||||||
if len(unrecognized) > 0 {
|
if len(unrecognized) > 0 {
|
||||||
return nil, newErr("invalid_scope", "Unrecognized scope(s) %q", unrecognized)
|
return nil, newErr(errInvalidScope, "Unrecognized scope(s) %q", unrecognized)
|
||||||
}
|
}
|
||||||
if len(invalidScopes) > 0 {
|
if len(invalidScopes) > 0 {
|
||||||
return nil, newErr("invalid_scope", "Client can't request scope(s) %q", invalidScopes)
|
return nil, newErr(errInvalidScope, "Client can't request scope(s) %q", invalidScopes)
|
||||||
}
|
}
|
||||||
|
|
||||||
var rt struct {
|
var rt struct {
|
||||||
|
@ -509,7 +509,7 @@ func (s *Server) parseAuthorizationRequest(r *http.Request) (*storage.AuthReques
|
||||||
case responseTypeToken:
|
case responseTypeToken:
|
||||||
rt.token = true
|
rt.token = true
|
||||||
default:
|
default:
|
||||||
return nil, newErr("invalid_request", "Invalid response type %q", responseType)
|
return nil, newErr(errInvalidRequest, "Invalid response type %q", responseType)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !s.supportedResponseTypes[responseType] {
|
if !s.supportedResponseTypes[responseType] {
|
||||||
|
@ -518,14 +518,14 @@ func (s *Server) parseAuthorizationRequest(r *http.Request) (*storage.AuthReques
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(responseTypes) == 0 {
|
if len(responseTypes) == 0 {
|
||||||
return nil, newErr("invalid_requests", "No response_type provided")
|
return nil, newErr(errInvalidRequest, "No response_type provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
if rt.token && !rt.code && !rt.idToken {
|
if rt.token && !rt.code && !rt.idToken {
|
||||||
// "token" can't be provided by its own.
|
// "token" can't be provided by its own.
|
||||||
//
|
//
|
||||||
// https://openid.net/specs/openid-connect-core-1_0.html#Authentication
|
// https://openid.net/specs/openid-connect-core-1_0.html#Authentication
|
||||||
return nil, newErr("invalid_request", "Response type 'token' must be provided with type 'id_token' and/or 'code'")
|
return nil, newErr(errInvalidRequest, "Response type 'token' must be provided with type 'id_token' and/or 'code'")
|
||||||
}
|
}
|
||||||
if !rt.code {
|
if !rt.code {
|
||||||
// Either "id_token token" or "id_token" has been provided which implies the
|
// Either "id_token token" or "id_token" has been provided which implies the
|
||||||
|
@ -533,13 +533,13 @@ func (s *Server) parseAuthorizationRequest(r *http.Request) (*storage.AuthReques
|
||||||
//
|
//
|
||||||
// https://openid.net/specs/openid-connect-core-1_0.html#ImplicitAuthRequest
|
// https://openid.net/specs/openid-connect-core-1_0.html#ImplicitAuthRequest
|
||||||
if nonce == "" {
|
if nonce == "" {
|
||||||
return nil, newErr("invalid_request", "Response type 'token' requires a 'nonce' value.")
|
return nil, newErr(errInvalidRequest, "Response type 'token' requires a 'nonce' value.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if rt.token {
|
if rt.token {
|
||||||
if redirectURI == redirectURIOOB {
|
if redirectURI == redirectURIOOB {
|
||||||
err := fmt.Sprintf("Cannot use response type 'token' with redirect_uri '%s'.", redirectURIOOB)
|
err := fmt.Sprintf("Cannot use response type 'token' with redirect_uri '%s'.", redirectURIOOB)
|
||||||
return nil, newErr("invalid_request", err)
|
return nil, newErr(errInvalidRequest, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
"gopkg.in/square/go-jose.v2"
|
"gopkg.in/square/go-jose.v2"
|
||||||
|
|
||||||
"github.com/dexidp/dex/storage"
|
"github.com/dexidp/dex/storage"
|
||||||
|
@ -27,6 +28,7 @@ func TestParseAuthorizationRequest(t *testing.T) {
|
||||||
queryParams map[string]string
|
queryParams map[string]string
|
||||||
|
|
||||||
wantErr bool
|
wantErr bool
|
||||||
|
exactError *authErr
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "normal request",
|
name: "normal request",
|
||||||
|
@ -269,6 +271,29 @@ func TestParseAuthorizationRequest(t *testing.T) {
|
||||||
},
|
},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "No response type",
|
||||||
|
clients: []storage.Client{
|
||||||
|
{
|
||||||
|
ID: "bar",
|
||||||
|
RedirectURIs: []string{"https://example.com/bar"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
supportedResponseTypes: []string{"code"},
|
||||||
|
queryParams: map[string]string{
|
||||||
|
"client_id": "bar",
|
||||||
|
"redirect_uri": "https://example.com/bar",
|
||||||
|
"code_challenge": "123",
|
||||||
|
"code_challenge_method": "plain",
|
||||||
|
"scope": "openid email profile",
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
exactError: &authErr{
|
||||||
|
RedirectURI: "https://example.com/bar",
|
||||||
|
Type: "invalid_request",
|
||||||
|
Description: "No response_type provided",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range tests {
|
for _, tc := range tests {
|
||||||
|
@ -294,12 +319,15 @@ func TestParseAuthorizationRequest(t *testing.T) {
|
||||||
} else {
|
} else {
|
||||||
req = httptest.NewRequest("GET", httpServer.URL+"/auth?"+params.Encode(), nil)
|
req = httptest.NewRequest("GET", httpServer.URL+"/auth?"+params.Encode(), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := server.parseAuthorizationRequest(req)
|
_, err := server.parseAuthorizationRequest(req)
|
||||||
if err != nil && !tc.wantErr {
|
if tc.wantErr {
|
||||||
t.Errorf("%s: %v", tc.name, err)
|
require.Error(t, err)
|
||||||
|
if tc.exactError != nil {
|
||||||
|
require.Equal(t, tc.exactError, err)
|
||||||
}
|
}
|
||||||
if err == nil && tc.wantErr {
|
} else {
|
||||||
t.Errorf("%s: expected error", tc.name)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue