mirror of
https://github.com/goharbor/harbor
synced 2025-04-19 08:02:22 +00:00
fix: validate the existence of project for export cve api (#17437)
Validate the existence of the project for export CVE API handler, return not found error if the project is not exist. Closes: #17430 Signed-off-by: chlins <chenyuzh@vmware.com>
This commit is contained in:
parent
5d7a549620
commit
31a3c6d18c
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/go-openapi/strfmt"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/rbac"
|
||||
"github.com/goharbor/harbor/src/controller/project"
|
||||
"github.com/goharbor/harbor/src/controller/scandataexport"
|
||||
"github.com/goharbor/harbor/src/jobservice/job"
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
|
@ -29,6 +30,7 @@ import (
|
|||
func newScanDataExportAPI() *scanDataExportAPI {
|
||||
return &scanDataExportAPI{
|
||||
scanDataExportCtl: scandataexport.Ctl,
|
||||
proCtl: project.Ctl,
|
||||
sysArtifactMgr: systemartifact.Mgr,
|
||||
userMgr: user.Mgr,
|
||||
}
|
||||
|
@ -37,6 +39,7 @@ func newScanDataExportAPI() *scanDataExportAPI {
|
|||
type scanDataExportAPI struct {
|
||||
BaseAPI
|
||||
scanDataExportCtl scandataexport.Controller
|
||||
proCtl project.Controller
|
||||
sysArtifactMgr systemartifact.Manager
|
||||
userMgr user.Manager
|
||||
}
|
||||
|
@ -47,7 +50,7 @@ func (se *scanDataExportAPI) Prepare(ctx context.Context, operation string, para
|
|||
|
||||
func (se *scanDataExportAPI) ExportScanData(ctx context.Context, params operation.ExportScanDataParams) middleware.Responder {
|
||||
// validate the request params
|
||||
if err := validateScanExportParams(params); err != nil {
|
||||
if err := se.validateScanExportParams(ctx, params); err != nil {
|
||||
return se.SendError(ctx, err)
|
||||
}
|
||||
|
||||
|
@ -55,13 +58,6 @@ func (se *scanDataExportAPI) ExportScanData(ctx context.Context, params operatio
|
|||
return se.SendError(ctx, err)
|
||||
}
|
||||
|
||||
// check if the MIME type for the export is the Generic vulnerability data
|
||||
if params.XScanDataType != v1.MimeTypeGenericVulnerabilityReport {
|
||||
error := &models.Error{Message: fmt.Sprintf("Unsupported MIME type : %s", params.XScanDataType)}
|
||||
errors := &models.Errors{Errors: []*models.Error{error}}
|
||||
return operation.NewExportScanDataBadRequest().WithPayload(errors)
|
||||
}
|
||||
|
||||
scanDataExportJob := new(models.ScanDataExportJob)
|
||||
|
||||
secContext, err := se.GetSecurityContext(ctx)
|
||||
|
@ -309,10 +305,17 @@ func (se *scanDataExportAPI) requireProjectsAccess(ctx context.Context, pids []i
|
|||
// validateScanExportParams validates scan data export request parameters by
|
||||
// following policies.
|
||||
// rules:
|
||||
// 1. the criteria should not be empty
|
||||
// 2. currently only the export of single project is open
|
||||
// 3. do not allow to input space in the repo/tag/cve_id (space will lead to misjudge for doublestar filter)
|
||||
func validateScanExportParams(params operation.ExportScanDataParams) error {
|
||||
// 1. check the scan data type
|
||||
// 2. the criteria should not be empty
|
||||
// 3. currently only the export of single project is open
|
||||
// 4. check the existence of project
|
||||
// 5. do not allow to input space in the repo/tag/cve_id (space will lead to misjudge for doublestar filter)
|
||||
func (se *scanDataExportAPI) validateScanExportParams(ctx context.Context, params operation.ExportScanDataParams) error {
|
||||
// check if the MIME type for the export is the Generic vulnerability data
|
||||
if params.XScanDataType != v1.MimeTypeGenericVulnerabilityReport {
|
||||
return errors.BadRequestError(errors.Errorf("Unsupported MIME type : %s", params.XScanDataType))
|
||||
}
|
||||
|
||||
criteria := params.Criteria
|
||||
if criteria == nil {
|
||||
return errors.BadRequestError(errors.Errorf("criteria is invalid: %v", criteria))
|
||||
|
@ -323,6 +326,16 @@ func validateScanExportParams(params operation.ExportScanDataParams) error {
|
|||
return errors.BadRequestError(errors.Errorf("only support export single project, invalid value: %v", criteria.Projects))
|
||||
}
|
||||
|
||||
// check whether the project exists
|
||||
exist, err := se.proCtl.Exists(ctx, criteria.Projects[0])
|
||||
if err != nil {
|
||||
return errors.UnknownError(errors.Errorf("check the existence of project error: %v", err))
|
||||
}
|
||||
|
||||
if !exist {
|
||||
return errors.NotFoundError(errors.Errorf("project %d not found", criteria.Projects[0]))
|
||||
}
|
||||
|
||||
// check spaces
|
||||
space := " "
|
||||
inspectList := []string{criteria.Repositories, criteria.Tags, criteria.CVEIds}
|
||||
|
|
|
@ -2,6 +2,7 @@ package handler
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -22,6 +23,7 @@ import (
|
|||
"github.com/goharbor/harbor/src/server/v2.0/models"
|
||||
"github.com/goharbor/harbor/src/server/v2.0/restapi"
|
||||
operation "github.com/goharbor/harbor/src/server/v2.0/restapi/operations/scan_data_export"
|
||||
"github.com/goharbor/harbor/src/testing/controller/project"
|
||||
"github.com/goharbor/harbor/src/testing/controller/scandataexport"
|
||||
"github.com/goharbor/harbor/src/testing/mock"
|
||||
systemartifacttesting "github.com/goharbor/harbor/src/testing/pkg/systemartifact"
|
||||
|
@ -32,6 +34,7 @@ import (
|
|||
type ScanExportTestSuite struct {
|
||||
htesting.Suite
|
||||
scanExportCtl *scandataexport.Controller
|
||||
proCtl *project.Controller
|
||||
sysArtifactMgr *systemartifacttesting.Manager
|
||||
userMgr *user.Manager
|
||||
}
|
||||
|
@ -43,15 +46,18 @@ func (suite *ScanExportTestSuite) SetupSuite() {
|
|||
func (suite *ScanExportTestSuite) SetupTest() {
|
||||
|
||||
suite.scanExportCtl = &scandataexport.Controller{}
|
||||
suite.proCtl = &project.Controller{}
|
||||
suite.sysArtifactMgr = &systemartifacttesting.Manager{}
|
||||
suite.userMgr = &user.Manager{}
|
||||
suite.Config = &restapi.Config{
|
||||
ScanDataExportAPI: &scanDataExportAPI{
|
||||
scanDataExportCtl: suite.scanExportCtl,
|
||||
proCtl: suite.proCtl,
|
||||
sysArtifactMgr: suite.sysArtifactMgr,
|
||||
userMgr: suite.userMgr,
|
||||
},
|
||||
}
|
||||
mock.OnAnything(suite.proCtl, "Exists").Return(true, nil)
|
||||
suite.Suite.SetupSuite()
|
||||
}
|
||||
|
||||
|
@ -95,8 +101,17 @@ func (suite *ScanExportTestSuite) TestAuthorization() {
|
|||
}
|
||||
|
||||
func (suite *ScanExportTestSuite) TestValidateScanExportParams() {
|
||||
// empty criteria should return error
|
||||
err := validateScanExportParams(operation.ExportScanDataParams{})
|
||||
api := newScanDataExportAPI()
|
||||
api.proCtl = suite.proCtl
|
||||
ctx := context.TODO()
|
||||
// no scan data type should return error
|
||||
err := api.validateScanExportParams(ctx, operation.ExportScanDataParams{})
|
||||
suite.Error(err)
|
||||
suite.True(errors.IsErr(err, errors.BadRequestCode))
|
||||
|
||||
xScanDataType := v1.MimeTypeGenericVulnerabilityReport
|
||||
// empty params should return error
|
||||
err = api.validateScanExportParams(ctx, operation.ExportScanDataParams{XScanDataType: xScanDataType})
|
||||
suite.Error(err)
|
||||
suite.True(errors.IsErr(err, errors.BadRequestCode))
|
||||
|
||||
|
@ -104,7 +119,7 @@ func (suite *ScanExportTestSuite) TestValidateScanExportParams() {
|
|||
criteria := models.ScanDataExportRequest{
|
||||
Projects: []int64{200, 300},
|
||||
}
|
||||
err = validateScanExportParams(operation.ExportScanDataParams{Criteria: &criteria})
|
||||
err = api.validateScanExportParams(ctx, operation.ExportScanDataParams{XScanDataType: xScanDataType, Criteria: &criteria})
|
||||
suite.Error(err)
|
||||
suite.True(errors.IsErr(err, errors.BadRequestCode))
|
||||
|
||||
|
@ -116,7 +131,7 @@ func (suite *ScanExportTestSuite) TestValidateScanExportParams() {
|
|||
Repositories: "test-repo1, test-repo2",
|
||||
Tags: "{test-tag1, test-tag2}",
|
||||
}
|
||||
err = validateScanExportParams(operation.ExportScanDataParams{Criteria: &criteria})
|
||||
err = api.validateScanExportParams(ctx, operation.ExportScanDataParams{XScanDataType: xScanDataType, Criteria: &criteria})
|
||||
suite.Error(err)
|
||||
suite.True(errors.IsErr(err, errors.BadRequestCode))
|
||||
|
||||
|
@ -128,8 +143,22 @@ func (suite *ScanExportTestSuite) TestValidateScanExportParams() {
|
|||
Repositories: "test-repo1,test-repo2",
|
||||
Tags: "{test-tag1,test-tag2}",
|
||||
}
|
||||
err = validateScanExportParams(operation.ExportScanDataParams{Criteria: &criteria})
|
||||
err = api.validateScanExportParams(ctx, operation.ExportScanDataParams{XScanDataType: xScanDataType, Criteria: &criteria})
|
||||
suite.NoError(err)
|
||||
|
||||
// none exist project should return error
|
||||
api.proCtl = &project.Controller{}
|
||||
mock.OnAnything(api.proCtl, "Exists").Return(false, nil)
|
||||
criteria = models.ScanDataExportRequest{
|
||||
CVEIds: "CVE-123,CVE-456",
|
||||
Labels: []int64{100},
|
||||
Projects: []int64{200},
|
||||
Repositories: "test-repo1,test-repo2",
|
||||
Tags: "{test-tag1,test-tag2}",
|
||||
}
|
||||
err = api.validateScanExportParams(ctx, operation.ExportScanDataParams{XScanDataType: xScanDataType, Criteria: &criteria})
|
||||
suite.Error(err)
|
||||
suite.True(errors.IsErr(err, errors.NotFoundCode))
|
||||
}
|
||||
|
||||
func (suite *ScanExportTestSuite) TestExportScanData() {
|
||||
|
|
Loading…
Reference in New Issue
Block a user