forked from TrueCloudLab/distribution
Merge pull request #2048 from dmcgowan/use-api-errors
Update oauth errors to use api errors
This commit is contained in:
commit
717134d7c2
1 changed files with 28 additions and 25 deletions
|
@ -38,25 +38,6 @@ func (e *UnexpectedHTTPResponseError) Error() string {
|
||||||
return fmt.Sprintf("error parsing HTTP %d response body: %s: %q", e.StatusCode, e.ParseErr.Error(), string(e.Response))
|
return fmt.Sprintf("error parsing HTTP %d response body: %s: %q", e.StatusCode, e.ParseErr.Error(), string(e.Response))
|
||||||
}
|
}
|
||||||
|
|
||||||
// OAuthError is returned when the request could not be authorized
|
|
||||||
// using the provided oauth token. This could represent a lack of
|
|
||||||
// permission or invalid token given from a token server.
|
|
||||||
// See https://tools.ietf.org/html/rfc6750#section-3
|
|
||||||
type OAuthError struct {
|
|
||||||
// ErrorCode is a code defined in https://tools.ietf.org/html/rfc6750#section-3.1
|
|
||||||
ErrorCode string
|
|
||||||
|
|
||||||
// Description is the error description associated with the error code
|
|
||||||
Description string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *OAuthError) Error() string {
|
|
||||||
if e.Description != "" {
|
|
||||||
return fmt.Sprintf("oauth error %q: %s", e.ErrorCode, e.Description)
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("oauth error %q", e.ErrorCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseHTTPErrorResponse(statusCode int, r io.Reader) error {
|
func parseHTTPErrorResponse(statusCode int, r io.Reader) error {
|
||||||
var errors errcode.Errors
|
var errors errcode.Errors
|
||||||
body, err := ioutil.ReadAll(r)
|
body, err := ioutil.ReadAll(r)
|
||||||
|
@ -102,6 +83,17 @@ func parseHTTPErrorResponse(statusCode int, r io.Reader) error {
|
||||||
return errors
|
return errors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeErrorList(err error) []error {
|
||||||
|
if errL, ok := err.(errcode.Errors); ok {
|
||||||
|
return []error(errL)
|
||||||
|
}
|
||||||
|
return []error{err}
|
||||||
|
}
|
||||||
|
|
||||||
|
func mergeErrors(err1, err2 error) error {
|
||||||
|
return errcode.Errors(append(makeErrorList(err1), makeErrorList(err2)...))
|
||||||
|
}
|
||||||
|
|
||||||
// HandleErrorResponse returns error parsed from HTTP response for an
|
// HandleErrorResponse returns error parsed from HTTP response for an
|
||||||
// unsuccessful HTTP response code (in the range 400 - 499 inclusive). An
|
// unsuccessful HTTP response code (in the range 400 - 499 inclusive). An
|
||||||
// UnexpectedHTTPStatusError returned for response code outside of expected
|
// UnexpectedHTTPStatusError returned for response code outside of expected
|
||||||
|
@ -109,15 +101,26 @@ func parseHTTPErrorResponse(statusCode int, r io.Reader) error {
|
||||||
func HandleErrorResponse(resp *http.Response) error {
|
func HandleErrorResponse(resp *http.Response) error {
|
||||||
if resp.StatusCode >= 400 && resp.StatusCode < 500 {
|
if resp.StatusCode >= 400 && resp.StatusCode < 500 {
|
||||||
// Check for OAuth errors within the `WWW-Authenticate` header first
|
// Check for OAuth errors within the `WWW-Authenticate` header first
|
||||||
|
// See https://tools.ietf.org/html/rfc6750#section-3
|
||||||
for _, c := range challenge.ResponseChallenges(resp) {
|
for _, c := range challenge.ResponseChallenges(resp) {
|
||||||
if c.Scheme == "bearer" {
|
if c.Scheme == "bearer" {
|
||||||
errStr := c.Parameters["error"]
|
var err errcode.Error
|
||||||
if errStr != "" {
|
// codes defined at https://tools.ietf.org/html/rfc6750#section-3.1
|
||||||
return &OAuthError{
|
switch c.Parameters["error"] {
|
||||||
ErrorCode: errStr,
|
case "invalid_token":
|
||||||
Description: c.Parameters["error_description"],
|
err.Code = errcode.ErrorCodeUnauthorized
|
||||||
}
|
case "insufficient_scope":
|
||||||
|
err.Code = errcode.ErrorCodeDenied
|
||||||
|
default:
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
if description := c.Parameters["error_description"]; description != "" {
|
||||||
|
err.Message = description
|
||||||
|
} else {
|
||||||
|
err.Message = err.Code.Message()
|
||||||
|
}
|
||||||
|
|
||||||
|
return mergeErrors(err, parseHTTPErrorResponse(resp.StatusCode, resp.Body))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err := parseHTTPErrorResponse(resp.StatusCode, resp.Body)
|
err := parseHTTPErrorResponse(resp.StatusCode, resp.Body)
|
||||||
|
|
Loading…
Reference in a new issue