/* * MinIO Cloud Storage, (C) 2018 MinIO, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package cmd import ( "context" "encoding/xml" "fmt" "net/http" xhttp "github.com/minio/minio/cmd/http" "github.com/minio/minio/cmd/logger" ) // writeSTSErrorRespone writes error headers func writeSTSErrorResponse(ctx context.Context, w http.ResponseWriter, errCode STSErrorCode, errCtxt error) { err := stsErrCodes.ToSTSErr(errCode) // Generate error response. stsErrorResponse := STSErrorResponse{} stsErrorResponse.Error.Code = err.Code stsErrorResponse.RequestID = w.Header().Get(xhttp.AmzRequestID) stsErrorResponse.Error.Message = err.Description if errCtxt != nil { stsErrorResponse.Error.Message = fmt.Sprintf("%v", errCtxt) } logKind := logger.All switch errCode { case ErrSTSInternalError, ErrSTSNotInitialized: logKind = logger.Minio default: logKind = logger.Application } logger.LogIf(ctx, errCtxt, logKind) encodedErrorResponse := encodeResponse(stsErrorResponse) writeResponse(w, err.HTTPStatusCode, encodedErrorResponse, mimeXML) } // STSError structure type STSError struct { Code string Description string HTTPStatusCode int } // STSErrorResponse - error response format type STSErrorResponse struct { XMLName xml.Name `xml:"https://sts.amazonaws.com/doc/2011-06-15/ ErrorResponse" json:"-"` Error struct { Type string `xml:"Type"` Code string `xml:"Code"` Message string `xml:"Message"` } `xml:"Error"` RequestID string `xml:"RequestId"` } // STSErrorCode type of error status. type STSErrorCode int // Error codes, non exhaustive list - http://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithSAML.html const ( ErrSTSNone STSErrorCode = iota ErrSTSAccessDenied ErrSTSMissingParameter ErrSTSInvalidParameterValue ErrSTSWebIdentityExpiredToken ErrSTSClientGrantsExpiredToken ErrSTSInvalidClientGrantsToken ErrSTSMalformedPolicyDocument ErrSTSNotInitialized ErrSTSInternalError ) type stsErrorCodeMap map[STSErrorCode]STSError func (e stsErrorCodeMap) ToSTSErr(errCode STSErrorCode) STSError { apiErr, ok := e[errCode] if !ok { return e[ErrSTSInternalError] } return apiErr } // error code to STSError structure, these fields carry respective // descriptions for all the error responses. var stsErrCodes = stsErrorCodeMap{ ErrSTSAccessDenied: { Code: "AccessDenied", Description: "Generating temporary credentials not allowed for this request.", HTTPStatusCode: http.StatusForbidden, }, ErrSTSMissingParameter: { Code: "MissingParameter", Description: "A required parameter for the specified action is not supplied.", HTTPStatusCode: http.StatusBadRequest, }, ErrSTSInvalidParameterValue: { Code: "InvalidParameterValue", Description: "An invalid or out-of-range value was supplied for the input parameter.", HTTPStatusCode: http.StatusBadRequest, }, ErrSTSWebIdentityExpiredToken: { Code: "ExpiredToken", Description: "The web identity token that was passed is expired or is not valid. Get a new identity token from the identity provider and then retry the request.", HTTPStatusCode: http.StatusBadRequest, }, ErrSTSClientGrantsExpiredToken: { Code: "ExpiredToken", Description: "The client grants that was passed is expired or is not valid. Get a new client grants token from the identity provider and then retry the request.", HTTPStatusCode: http.StatusBadRequest, }, ErrSTSInvalidClientGrantsToken: { Code: "InvalidClientGrantsToken", Description: "The client grants token that was passed could not be validated by MinIO.", HTTPStatusCode: http.StatusBadRequest, }, ErrSTSMalformedPolicyDocument: { Code: "MalformedPolicyDocument", Description: "The request was rejected because the policy document was malformed.", HTTPStatusCode: http.StatusBadRequest, }, ErrSTSNotInitialized: { Code: "STSNotInitialized", Description: "STS API not initialized, please try again.", HTTPStatusCode: http.StatusServiceUnavailable, }, ErrSTSInternalError: { Code: "InternalError", Description: "We encountered an internal error generating credentials, please try again.", HTTPStatusCode: http.StatusInternalServerError, }, } // getSTSErrorResponse gets in standard error and // provides a encodable populated response values func getSTSErrorResponse(err STSError, requestID string) STSErrorResponse { errRsp := STSErrorResponse{} errRsp.Error.Code = err.Code errRsp.Error.Message = err.Description errRsp.RequestID = requestID return errRsp }