Skip to content

Commit

Permalink
permission grant for scanner related actions are not correctly
Browse files Browse the repository at this point in the history
- add new endpoint for getting scanner candidates of specified project
- adjust the permission granting functions
- fix goharbor#9608

Signed-off-by: Steven Zou <[email protected]>
  • Loading branch information
steven-zou committed Oct 28, 2019
1 parent 5c4c04a commit 5b2ab34
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/common/rbac/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,6 @@ const (
ResourceRobot = Resource("robot")
ResourceNotificationPolicy = Resource("notification-policy")
ResourceScan = Resource("scan")
ResourceScanner = Resource("scanner")
ResourceSelf = Resource("") // subresource for self
)
3 changes: 3 additions & 0 deletions src/common/rbac/project/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 15 additions & 0 deletions src/common/rbac/project/visitor_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down Expand Up @@ -211,6 +214,8 @@ var (

{Resource: rbac.ResourceScan, Action: rbac.ActionCreate},
{Resource: rbac.ResourceScan, Action: rbac.ActionRead},

{Resource: rbac.ResourceScanner, Action: rbac.ActionRead},
},

"developer": {
Expand Down Expand Up @@ -266,6 +271,8 @@ var (

{Resource: rbac.ResourceScan, Action: rbac.ActionCreate},
{Resource: rbac.ResourceScan, Action: rbac.ActionRead},

{Resource: rbac.ResourceScanner, Action: rbac.ActionRead},
},

"guest": {
Expand Down Expand Up @@ -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": {
Expand All @@ -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},
},
}
)
Expand Down
1 change: 1 addition & 0 deletions src/core/api/harborapi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{}
Expand Down
35 changes: 33 additions & 2 deletions src/core/api/pro_scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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
}

Expand All @@ -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
}

Expand All @@ -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()
}
31 changes: 31 additions & 0 deletions src/core/api/pro_scanner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
}
1 change: 1 addition & 0 deletions src/core/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{}
Expand Down
22 changes: 22 additions & 0 deletions src/pkg/scan/api/scanner/base_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -26,6 +27,8 @@ import (

const (
proScannerMetaKey = "projectScanner"
statusUnhealthy = "unhealthy"
statusHealthy = "healthy"
)

// DefaultController is a singleton api controller for plug scanners
Expand Down Expand Up @@ -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
}

Expand Down
7 changes: 6 additions & 1 deletion src/pkg/scan/dao/scanner/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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"`
Expand Down

0 comments on commit 5b2ab34

Please sign in to comment.