Update oauth errors to use api errors
Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)master
							parent
							
								
									16396a7a80
								
							
						
					
					
						commit
						051801f1d0
					
				|  | @ -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 New Issue