mirror of
https://github.com/goharbor/harbor
synced 2024-09-21 00:29:56 +00:00
Merge pull request #5466 from steven-zou/fix_wrong_status_of_prov
Fix issues described in #5464 and #5465
This commit is contained in:
commit
3031e851ea
|
@ -83,24 +83,26 @@ func (mh *ManipulationHandler) GetChartVersion(w http.ResponseWriter, req *http.
|
||||||
return
|
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
|
//Query cache
|
||||||
chartDetails := mh.chartCache.GetChart(chartV.Digest)
|
chartDetails := mh.chartCache.GetChart(chartV.Digest)
|
||||||
if chartDetails == nil {
|
if chartDetails == nil {
|
||||||
//NOT hit!!
|
//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])
|
content, err := mh.getChartVersionContent(namespace, chartV.URLs[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
WriteInternalError(w, err)
|
WriteInternalError(w, err)
|
||||||
|
@ -115,26 +117,6 @@ func (mh *ManipulationHandler) GetChartVersion(w http.ResponseWriter, req *http.
|
||||||
}
|
}
|
||||||
chartDetails.Metadata = chartV
|
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
|
//Put it into the cache for next access
|
||||||
mh.chartCache.PutChart(chartDetails)
|
mh.chartCache.PutChart(chartDetails)
|
||||||
} else {
|
} else {
|
||||||
|
@ -144,6 +126,28 @@ func (mh *ManipulationHandler) GetChartVersion(w http.ResponseWriter, req *http.
|
||||||
chartDetails.Metadata.Version,
|
chartDetails.Metadata.Version,
|
||||||
chartDetails.Metadata.Digest)
|
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)
|
bytes, err := json.Marshal(chartDetails)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -263,13 +263,13 @@ func (cra *ChartRepositoryAPI) requireNamespace(namespace string) bool {
|
||||||
existsing, err := cra.ProjectMgr.Exists(namespace)
|
existsing, err := cra.ProjectMgr.Exists(namespace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//Check failed with error
|
//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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
//Not existing
|
//Not existing
|
||||||
if !existsing {
|
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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,7 +312,7 @@ func (cra *ChartRepositoryAPI) requireAccess(namespace string, accessLevel uint)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
//access rejected for invalid scope
|
//access rejected for invalid scope
|
||||||
cra.RenderError(http.StatusForbidden, "unrecognized access scope")
|
cra.renderError(http.StatusForbidden, "unrecognized access scope")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,40 +320,21 @@ func (cra *ChartRepositoryAPI) requireAccess(namespace string, accessLevel uint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//Unauthenticated, return 401
|
//Unauthenticated, return 401
|
||||||
if !cra.SecurityCtx.IsAuthenticated() {
|
if !cra.SecurityCtx.IsAuthenticated() {
|
||||||
cra.HandleUnauthorized()
|
cra.renderError(http.StatusUnauthorized, "Unauthorized")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
//Authenticated, return 403
|
//Authenticated, return 403
|
||||||
cra.RenderError(http.StatusForbidden, err.Error())
|
cra.renderError(http.StatusForbidden, err.Error())
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
//Initialize the chart service controller
|
//write error message with unified format
|
||||||
func initializeChartController() (*chartserver.Controller, error) {
|
func (cra *ChartRepositoryAPI) renderError(code int, text string) {
|
||||||
addr, err := config.GetChartMuseumEndpoint()
|
chartserver.WriteError(cra.Ctx.ResponseWriter, code, errors.New(text))
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//formFile is used to represent the uploaded files in the form
|
//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
|
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"
|
//Check if the request content type is "multipart/form-data"
|
||||||
func isMultipartFormData(req *http.Request) bool {
|
func isMultipartFormData(req *http.Request) bool {
|
||||||
return strings.Contains(req.Header.Get(headerContentType), contentTypeMultipart)
|
return strings.Contains(req.Header.Get(headerContentType), contentTypeMultipart)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user