github.com/cloudfoundry/cli@v7.1.0+incompatible/api/uaa/error_converter.go (about)

     1  package uaa
     2  
     3  import (
     4  	"encoding/json"
     5  	"net/http"
     6  )
     7  
     8  // errorWrapper is the wrapper that converts responses with 4xx and 5xx status
     9  // codes to an error.
    10  type errorWrapper struct {
    11  	connection Connection
    12  }
    13  
    14  // NewErrorWrapper returns a new error wrapper.
    15  func NewErrorWrapper() *errorWrapper {
    16  	return new(errorWrapper)
    17  }
    18  
    19  // Make converts RawHTTPStatusError, which represents responses with 4xx and
    20  // 5xx status codes, to specific errors.
    21  func (e *errorWrapper) Make(request *http.Request, passedResponse *Response) error {
    22  	err := e.connection.Make(request, passedResponse)
    23  
    24  	if rawHTTPStatusErr, ok := err.(RawHTTPStatusError); ok {
    25  		return convert(rawHTTPStatusErr)
    26  	}
    27  
    28  	return err
    29  }
    30  
    31  // Wrap wraps a UAA connection in this error handling wrapper.
    32  func (e *errorWrapper) Wrap(innerconnection Connection) Connection {
    33  	e.connection = innerconnection
    34  	return e
    35  }
    36  
    37  func convert(rawHTTPStatusErr RawHTTPStatusError) error {
    38  	// Try to unmarshal the raw http status error into a UAA error. If
    39  	// unmarshaling fails, return the raw error.
    40  	var uaaErrorResponse UAAErrorResponse
    41  	err := json.Unmarshal(rawHTTPStatusErr.RawResponse, &uaaErrorResponse)
    42  	if err != nil {
    43  		return rawHTTPStatusErr
    44  	}
    45  
    46  	switch rawHTTPStatusErr.StatusCode {
    47  	case http.StatusBadRequest: // 400
    48  		if uaaErrorResponse.Type == "invalid_scim_resource" {
    49  			return InvalidSCIMResourceError{Message: uaaErrorResponse.Description}
    50  		}
    51  		return rawHTTPStatusErr
    52  	case http.StatusUnauthorized: // 401
    53  		if uaaErrorResponse.Type == "invalid_token" {
    54  			return InvalidAuthTokenError{Message: uaaErrorResponse.Description}
    55  		}
    56  		if uaaErrorResponse.Type == "unauthorized" {
    57  			if uaaErrorResponse.Description == "Your account has been locked because of too many failed attempts to login." {
    58  				return AccountLockedError{Message: "Your account has been locked because of too many failed attempts to login."}
    59  			}
    60  			return UnauthorizedError{Message: uaaErrorResponse.Description}
    61  		}
    62  		return rawHTTPStatusErr
    63  	case http.StatusForbidden: // 403
    64  		if uaaErrorResponse.Type == "insufficient_scope" {
    65  			return InsufficientScopeError{Message: uaaErrorResponse.Description}
    66  		}
    67  		return rawHTTPStatusErr
    68  	case http.StatusConflict: // 409
    69  		return ConflictError{Message: uaaErrorResponse.Description}
    70  	case http.StatusUnprocessableEntity: // 422
    71  		if uaaErrorResponse.Type == "invalid_password" {
    72  			return InvalidPasswordError{Message: uaaErrorResponse.Description}
    73  		}
    74  		return rawHTTPStatusErr
    75  	default:
    76  		return rawHTTPStatusErr
    77  	}
    78  }