mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-23 02:35:17 +01:00
permission grant for scanner related actions are not correctly
- add new endpoint for getting scanner candidates of specified project - adjust the permission granting functions - fix #9608 Signed-off-by: Steven Zou <szou@vmware.com>
This commit is contained in:
parent
5c4c04a122
commit
5b2ab34e03
@ -61,5 +61,6 @@ const (
|
||||
ResourceRobot = Resource("robot")
|
||||
ResourceNotificationPolicy = Resource("notification-policy")
|
||||
ResourceScan = Resource("scan")
|
||||
ResourceScanner = Resource("scanner")
|
||||
ResourceSelf = Resource("") // subresource for self
|
||||
)
|
||||
|
@ -45,6 +45,9 @@ var (
|
||||
|
||||
{Resource: rbac.ResourceHelmChartVersion, Action: rbac.ActionRead},
|
||||
{Resource: rbac.ResourceHelmChartVersion, Action: rbac.ActionList},
|
||||
|
||||
{Resource: rbac.ResourceScan, Action: rbac.ActionRead},
|
||||
{Resource: rbac.ResourceScanner, Action: rbac.ActionRead},
|
||||
}
|
||||
|
||||
// all policies for the projects
|
||||
|
@ -124,6 +124,9 @@ var (
|
||||
|
||||
{Resource: rbac.ResourceScan, Action: rbac.ActionCreate},
|
||||
{Resource: rbac.ResourceScan, Action: rbac.ActionRead},
|
||||
|
||||
{Resource: rbac.ResourceScanner, Action: rbac.ActionRead},
|
||||
{Resource: rbac.ResourceScanner, Action: rbac.ActionCreate},
|
||||
},
|
||||
|
||||
"master": {
|
||||
@ -211,6 +214,8 @@ var (
|
||||
|
||||
{Resource: rbac.ResourceScan, Action: rbac.ActionCreate},
|
||||
{Resource: rbac.ResourceScan, Action: rbac.ActionRead},
|
||||
|
||||
{Resource: rbac.ResourceScanner, Action: rbac.ActionRead},
|
||||
},
|
||||
|
||||
"developer": {
|
||||
@ -266,6 +271,8 @@ var (
|
||||
|
||||
{Resource: rbac.ResourceScan, Action: rbac.ActionCreate},
|
||||
{Resource: rbac.ResourceScan, Action: rbac.ActionRead},
|
||||
|
||||
{Resource: rbac.ResourceScanner, Action: rbac.ActionRead},
|
||||
},
|
||||
|
||||
"guest": {
|
||||
@ -306,6 +313,10 @@ var (
|
||||
|
||||
{Resource: rbac.ResourceRobot, Action: rbac.ActionRead},
|
||||
{Resource: rbac.ResourceRobot, Action: rbac.ActionList},
|
||||
|
||||
{Resource: rbac.ResourceScan, Action: rbac.ActionRead},
|
||||
|
||||
{Resource: rbac.ResourceScanner, Action: rbac.ActionRead},
|
||||
},
|
||||
|
||||
"limitedGuest": {
|
||||
@ -330,6 +341,10 @@ var (
|
||||
{Resource: rbac.ResourceHelmChartVersion, Action: rbac.ActionList},
|
||||
|
||||
{Resource: rbac.ResourceConfiguration, Action: rbac.ActionRead},
|
||||
|
||||
{Resource: rbac.ResourceScan, Action: rbac.ActionRead},
|
||||
|
||||
{Resource: rbac.ResourceScanner, Action: rbac.ActionRead},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
@ -217,6 +217,7 @@ func init() {
|
||||
// Add routes for project level scanner
|
||||
proScannerAPI := &ProjectScannerAPI{}
|
||||
beego.Router("/api/projects/:pid([0-9]+)/scanner", proScannerAPI, "get:GetProjectScanner;put:SetProjectScanner")
|
||||
beego.Router("/api/projects/:pid([0-9]+)/scanner/candidates", proScannerAPI, "get:GetProScannerCandidates")
|
||||
|
||||
// Add routes for scan
|
||||
scanAPI := &ScanAPI{}
|
||||
|
@ -16,6 +16,7 @@ package api
|
||||
|
||||
import (
|
||||
"github.com/goharbor/harbor/src/common/rbac"
|
||||
"github.com/goharbor/harbor/src/pkg/q"
|
||||
"github.com/goharbor/harbor/src/pkg/scan/api/scanner"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@ -67,7 +68,7 @@ func (sa *ProjectScannerAPI) Prepare() {
|
||||
// GetProjectScanner gets the project level scanner
|
||||
func (sa *ProjectScannerAPI) GetProjectScanner() {
|
||||
// Check access permissions
|
||||
if !sa.RequireProjectAccess(sa.pid, rbac.ActionRead, rbac.ResourceConfiguration) {
|
||||
if !sa.RequireProjectAccess(sa.pid, rbac.ActionRead, rbac.ResourceScanner) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -89,7 +90,7 @@ func (sa *ProjectScannerAPI) GetProjectScanner() {
|
||||
// SetProjectScanner sets the project level scanner
|
||||
func (sa *ProjectScannerAPI) SetProjectScanner() {
|
||||
// Check access permissions
|
||||
if !sa.RequireProjectAccess(sa.pid, rbac.ActionUpdate, rbac.ResourceConfiguration) {
|
||||
if !sa.RequireProjectAccess(sa.pid, rbac.ActionCreate, rbac.ResourceScanner) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -110,3 +111,33 @@ func (sa *ProjectScannerAPI) SetProjectScanner() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// GetProScannerCandidates gets the candidates for setting project level scanner.
|
||||
func (sa *ProjectScannerAPI) GetProScannerCandidates() {
|
||||
// Check access permissions
|
||||
// Same permission with project level scanner set action
|
||||
if !sa.RequireProjectAccess(sa.pid, rbac.ActionCreate, rbac.ResourceScanner) {
|
||||
return
|
||||
}
|
||||
|
||||
p, pz, err := sa.GetPaginationParams()
|
||||
if err != nil {
|
||||
sa.SendBadRequestError(errors.Wrap(err, "scanner API: get project scanner candidates"))
|
||||
return
|
||||
}
|
||||
|
||||
query := &q.Query{
|
||||
PageSize: pz,
|
||||
PageNumber: p,
|
||||
}
|
||||
|
||||
all, err := sa.c.ListRegistrations(query)
|
||||
if err != nil {
|
||||
sa.SendInternalServerError(errors.Wrap(err, "scanner API: get project scanner candidates"))
|
||||
return
|
||||
}
|
||||
|
||||
// Response to the client
|
||||
sa.Data["json"] = all
|
||||
sa.ServeJSON()
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/goharbor/harbor/src/pkg/q"
|
||||
"github.com/goharbor/harbor/src/pkg/scan/dao/scanner"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -93,3 +94,33 @@ func (suite *ProScannerAPITestSuite) TestScannerAPIProjectScanner() {
|
||||
assert.Equal(suite.T(), r.Name, rr.Name)
|
||||
assert.Equal(suite.T(), r.UUID, rr.UUID)
|
||||
}
|
||||
|
||||
// TestScannerAPIGetScannerCandidates ...
|
||||
func (suite *ProScannerAPITestSuite) TestScannerAPIGetScannerCandidates() {
|
||||
query := &q.Query{
|
||||
PageNumber: 1,
|
||||
PageSize: 500,
|
||||
}
|
||||
|
||||
ll := []*scanner.Registration{
|
||||
{
|
||||
ID: 1005,
|
||||
UUID: "uuid",
|
||||
Name: "TestScannerAPIGetScannerCandidates",
|
||||
Description: "JUST FOR TEST",
|
||||
URL: "https://a.b.c",
|
||||
}}
|
||||
suite.mockC.On("ListRegistrations", query).Return(ll, nil)
|
||||
|
||||
// Get
|
||||
l := make([]*scanner.Registration, 0)
|
||||
err := handleAndParse(&testingRequest{
|
||||
url: fmt.Sprintf("/api/projects/%d/scanner/candidates", 1),
|
||||
method: http.MethodGet,
|
||||
credential: projAdmin,
|
||||
}, &l)
|
||||
require.NoError(suite.T(), err)
|
||||
|
||||
assert.Equal(suite.T(), 1, len(l))
|
||||
assert.Equal(suite.T(), "uuid", l[0].UUID)
|
||||
}
|
||||
|
@ -204,6 +204,7 @@ func initRouters() {
|
||||
// Add routes for project level scanner
|
||||
proScannerAPI := &api.ProjectScannerAPI{}
|
||||
beego.Router("/api/projects/:pid([0-9]+)/scanner", proScannerAPI, "get:GetProjectScanner;put:SetProjectScanner")
|
||||
beego.Router("/api/projects/:pid([0-9]+)/scanner/candidates", proScannerAPI, "get:GetProScannerCandidates")
|
||||
|
||||
// Add routes for scan
|
||||
scanAPI := &api.ScanAPI{}
|
||||
|
@ -15,6 +15,7 @@
|
||||
package scanner
|
||||
|
||||
import (
|
||||
"github.com/goharbor/harbor/src/common/utils/log"
|
||||
"github.com/goharbor/harbor/src/core/promgr/metamgr"
|
||||
"github.com/goharbor/harbor/src/jobservice/logger"
|
||||
"github.com/goharbor/harbor/src/pkg/q"
|
||||
@ -26,6 +27,8 @@ import (
|
||||
|
||||
const (
|
||||
proScannerMetaKey = "projectScanner"
|
||||
statusUnhealthy = "unhealthy"
|
||||
statusHealthy = "healthy"
|
||||
)
|
||||
|
||||
// DefaultController is a singleton api controller for plug scanners
|
||||
@ -214,6 +217,25 @@ func (bc *basicController) GetRegistrationByProject(projectID int64) (*scanner.R
|
||||
}
|
||||
}
|
||||
|
||||
// No scanner configured
|
||||
if registration == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Get metadata of the configured registration
|
||||
meta, err := bc.Ping(registration)
|
||||
if err != nil {
|
||||
// Not blocked, just logged it
|
||||
log.Error(errors.Wrap(err, "api controller: get project scanner"))
|
||||
registration.Health = statusUnhealthy
|
||||
} else {
|
||||
registration.Health = statusHealthy
|
||||
// Fill in some metadata
|
||||
registration.Adapter = meta.Scanner.Name
|
||||
registration.Vendor = meta.Scanner.Vendor
|
||||
registration.Version = meta.Scanner.Version
|
||||
}
|
||||
|
||||
return registration, err
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ type Registration struct {
|
||||
URL string `orm:"column(url);unique;size(512)" json:"url"`
|
||||
Disabled bool `orm:"column(disabled);default(true)" json:"disabled"`
|
||||
IsDefault bool `orm:"column(is_default);default(false)" json:"is_default"`
|
||||
Health bool `orm:"-" json:"-"` // Reserved for future use
|
||||
Health string `orm:"-" json:"health,omitempty"`
|
||||
|
||||
// Authentication settings
|
||||
// "","Basic", "Bearer" and api key header "X-ScannerAdapter-API-Key" can be supported
|
||||
@ -53,6 +53,11 @@ type Registration struct {
|
||||
// Indicate if the registration is immutable which is not allowed to remove
|
||||
Immutable bool `orm:"column(immutable);default(false)" json:"-"`
|
||||
|
||||
// Optional properties for describing the adapter
|
||||
Adapter string `orm:"-" json:"adapter,omitempty"`
|
||||
Vendor string `orm:"-" json:"vendor,omitempty"`
|
||||
Version string `orm:"-" json:"version,omitempty"`
|
||||
|
||||
// Timestamps
|
||||
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
|
||||
UpdateTime time.Time `orm:"column(update_time);auto_now;type(datetime)" json:"update_time"`
|
||||
|
Loading…
Reference in New Issue
Block a user