1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
// Copyright 2022 The Sigstore Authors.
//
// 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 api
import (
"fmt"
"net/http"
"regexp"
"github.com/go-openapi/runtime/middleware"
"github.com/mitchellh/mapstructure"
"github.com/sigstore/timestamp-authority/v2/pkg/generated/models"
"github.com/sigstore/timestamp-authority/v2/pkg/generated/restapi/operations/timestamp"
"github.com/sigstore/timestamp-authority/v2/pkg/log"
)
const (
failedToGenerateTimestampResponse = "Error generating timestamp response"
excesssivelyLongOID = "OID should be comprised of at most 128 components"
WeakHashAlgorithmTimestampRequest = "Weak hash algorithm in timestamp request"
InconsistentDigestLengthTimestampRequest = "Message digest has incorrect length for specified algorithm"
)
func errorMsg(message string, code int) *models.Error {
return &models.Error{
Code: int64(code),
Message: message,
}
}
func handleTimestampAPIError(params interface{}, code int, err error, message string, fields ...interface{}) middleware.Responder {
if message == "" {
message = http.StatusText(code)
}
re := regexp.MustCompile("^(.*)Params$")
typeStr := fmt.Sprintf("%T", params)
handler := re.FindStringSubmatch(typeStr)[1]
logMsg := func(r *http.Request) {
if code < http.StatusInternalServerError {
log.RequestIDLogger(r).Warnw(message, append([]interface{}{"handler", handler, "statusCode", code, "error", err}, fields...)...)
} else {
log.RequestIDLogger(r).Errorw(message, append([]interface{}{"handler", handler, "statusCode", code, "error", err}, fields...)...)
}
paramsFields := map[string]interface{}{}
if err := mapstructure.Decode(params, ¶msFields); err == nil {
log.RequestIDLogger(r).Debug(paramsFields)
}
}
switch params := params.(type) {
case timestamp.GetTimestampResponseParams:
logMsg(params.HTTPRequest)
switch code {
case http.StatusBadRequest:
return timestamp.NewGetTimestampResponseBadRequest().WithPayload(errorMsg(message, code))
case http.StatusNotImplemented:
return timestamp.NewGetTimestampResponseNotImplemented()
default:
return timestamp.NewGetTimestampResponseDefault(code).WithPayload(errorMsg(message, code))
}
case timestamp.GetTimestampCertChainParams:
logMsg(params.HTTPRequest)
switch code {
case http.StatusNotFound:
return timestamp.NewGetTimestampCertChainNotFound()
default:
return timestamp.NewGetTimestampCertChainDefault(code).WithPayload(errorMsg(message, code))
}
default:
log.Logger.Errorf("unable to find method for type %T; error: %v", params, err)
return middleware.Error(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}
}
|