Merge pull request #5466 from steven-zou/fix_wrong_status_of_prov

Fix issues described in #5464 and #5465
This commit is contained in:
Wenkai Yin 2018-08-02 18:49:45 +08:00 committed by GitHub
commit 3031e851ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 70 additions and 61 deletions

View File

@ -83,24 +83,26 @@ func (mh *ManipulationHandler) GetChartVersion(w http.ResponseWriter, req *http.
return
}
//Get and check namespace
//even we get the data from cache
var namespace string
repoValue := req.Context().Value(NamespaceContextKey)
if repoValue != nil {
if ns, ok := repoValue.(string); ok {
namespace = ns
}
}
if len(strings.TrimSpace(namespace)) == 0 {
WriteInternalError(w, errors.New("failed to extract namespace from the request"))
return
}
//Query cache
chartDetails := mh.chartCache.GetChart(chartV.Digest)
if chartDetails == nil {
//NOT hit!!
var namespace string
repoValue := req.Context().Value(NamespaceContextKey)
if repoValue != nil {
if ns, ok := repoValue.(string); ok {
namespace = ns
}
}
if len(strings.TrimSpace(namespace)) == 0 {
WriteInternalError(w, errors.New("failed to extract namespace from the request"))
return
}
content, err := mh.getChartVersionContent(namespace, chartV.URLs[0])
if err != nil {
WriteInternalError(w, err)
@ -115,26 +117,6 @@ func (mh *ManipulationHandler) GetChartVersion(w http.ResponseWriter, req *http.
}
chartDetails.Metadata = chartV
//Generate the security report
//prov file share same endpoint with the chart version
//Just add .prov suffix to the chart version to form the path of prov file
//Anyway, there will be a report about the digital signature status
chartDetails.Security = &SecurityReport{
Signature: &DigitalSignature{
Signed: false,
},
}
//Try to get the prov file to confirm if it is exitsing
provFilePath := fmt.Sprintf("%s.prov", chartV.URLs[0])
provBytes, err := mh.getChartVersionContent(namespace, provFilePath)
if err == nil && len(provBytes) > 0 {
chartDetails.Security.Signature.Signed = true
chartDetails.Security.Signature.Provenance = provFilePath
} else {
//Just log it
hlog.Errorf("Failed to get prov file for chart %s with error: %s, got %d bytes", chartV.Name, err.Error(), len(provBytes))
}
//Put it into the cache for next access
mh.chartCache.PutChart(chartDetails)
} else {
@ -144,6 +126,28 @@ func (mh *ManipulationHandler) GetChartVersion(w http.ResponseWriter, req *http.
chartDetails.Metadata.Version,
chartDetails.Metadata.Digest)
}
//The change of prov file will not cause any influence to the digest of chart,
//and then the digital signature status should be not cached
//
//Generate the security report
//prov file share same endpoint with the chart version
//Just add .prov suffix to the chart version to form the path of prov file
//Anyway, there will be a report about the digital signature status
chartDetails.Security = &SecurityReport{
Signature: &DigitalSignature{
Signed: false,
},
}
//Try to get the prov file to confirm if it is exitsing
provFilePath := fmt.Sprintf("%s.prov", chartV.URLs[0])
provBytes, err := mh.getChartVersionContent(namespace, provFilePath)
if err == nil && len(provBytes) > 0 {
chartDetails.Security.Signature.Signed = true
chartDetails.Security.Signature.Provenance = provFilePath
} else {
//Just log it
hlog.Errorf("Failed to get prov file for chart %s with error: %s, got %d bytes", chartV.Name, err.Error(), len(provBytes))
}
bytes, err := json.Marshal(chartDetails)
if err != nil {

View File

@ -263,13 +263,13 @@ func (cra *ChartRepositoryAPI) requireNamespace(namespace string) bool {
existsing, err := cra.ProjectMgr.Exists(namespace)
if err != nil {
//Check failed with error
cra.RenderError(http.StatusInternalServerError, fmt.Sprintf("failed to check existence of namespace %s with error: %s", namespace, err.Error()))
cra.renderError(http.StatusInternalServerError, fmt.Sprintf("failed to check existence of namespace %s with error: %s", namespace, err.Error()))
return false
}
//Not existing
if !existsing {
cra.HandleBadRequest(fmt.Sprintf("namespace %s is not existing", namespace))
cra.renderError(http.StatusBadRequest, fmt.Sprintf("namespace %s is not existing", namespace))
return false
}
@ -312,7 +312,7 @@ func (cra *ChartRepositoryAPI) requireAccess(namespace string, accessLevel uint)
}
default:
//access rejected for invalid scope
cra.RenderError(http.StatusForbidden, "unrecognized access scope")
cra.renderError(http.StatusForbidden, "unrecognized access scope")
return false
}
@ -320,40 +320,21 @@ func (cra *ChartRepositoryAPI) requireAccess(namespace string, accessLevel uint)
if err != nil {
//Unauthenticated, return 401
if !cra.SecurityCtx.IsAuthenticated() {
cra.HandleUnauthorized()
cra.renderError(http.StatusUnauthorized, "Unauthorized")
return false
}
//Authenticated, return 403
cra.RenderError(http.StatusForbidden, err.Error())
cra.renderError(http.StatusForbidden, err.Error())
return false
}
return true
}
//Initialize the chart service controller
func initializeChartController() (*chartserver.Controller, error) {
addr, err := config.GetChartMuseumEndpoint()
if err != nil {
return nil, fmt.Errorf("Failed to get the endpoint URL of chart storage server: %s", err.Error())
}
addr = strings.TrimSuffix(addr, "/")
url, err := url.Parse(addr)
if err != nil {
return nil, errors.New("Endpoint URL of chart storage server is malformed")
}
controller, err := chartserver.NewController(url)
if err != nil {
return nil, errors.New("Failed to initialize chart API controller")
}
hlog.Debugf("Chart storage server is set to %s", url.String())
hlog.Info("API controller for chart repository server is successfully initialized")
return controller, nil
//write error message with unified format
func (cra *ChartRepositoryAPI) renderError(code int, text string) {
chartserver.WriteError(cra.Ctx.ResponseWriter, code, errors.New(text))
}
//formFile is used to represent the uploaded files in the form
@ -417,6 +398,30 @@ func (cra *ChartRepositoryAPI) rewriteFileContent(files []formFile, request *htt
return nil
}
//Initialize the chart service controller
func initializeChartController() (*chartserver.Controller, error) {
addr, err := config.GetChartMuseumEndpoint()
if err != nil {
return nil, fmt.Errorf("Failed to get the endpoint URL of chart storage server: %s", err.Error())
}
addr = strings.TrimSuffix(addr, "/")
url, err := url.Parse(addr)
if err != nil {
return nil, errors.New("Endpoint URL of chart storage server is malformed")
}
controller, err := chartserver.NewController(url)
if err != nil {
return nil, errors.New("Failed to initialize chart API controller")
}
hlog.Debugf("Chart storage server is set to %s", url.String())
hlog.Info("API controller for chart repository server is successfully initialized")
return controller, nil
}
//Check if the request content type is "multipart/form-data"
func isMultipartFormData(req *http.Request) bool {
return strings.Contains(req.Header.Get(headerContentType), contentTypeMultipart)