diff --git a/make/migrations/postgresql/0015_1.10.0_schema.up.sql b/make/migrations/postgresql/0015_1.10.0_schema.up.sql index a2904162e..44372ba93 100644 --- a/make/migrations/postgresql/0015_1.10.0_schema.up.sql +++ b/make/migrations/postgresql/0015_1.10.0_schema.up.sql @@ -42,4 +42,6 @@ CREATE TABLE immutable_tag_rule tag_filter text, enabled boolean default true NOT NULL, creation_time timestamp default CURRENT_TIMESTAMP -) \ No newline at end of file +); + +ALTER TABLE robot ADD COLUMN visible boolean DEFAULT true NOT NULL; \ No newline at end of file diff --git a/src/core/api/robot.go b/src/core/api/robot.go index 5c42629a8..1f6c2bdfd 100644 --- a/src/core/api/robot.go +++ b/src/core/api/robot.go @@ -20,6 +20,7 @@ import ( "github.com/goharbor/harbor/src/common/models" "github.com/goharbor/harbor/src/common/rbac" "github.com/goharbor/harbor/src/common/rbac/project" + "github.com/goharbor/harbor/src/pkg/q" "github.com/goharbor/harbor/src/pkg/robot" "github.com/goharbor/harbor/src/pkg/robot/model" "github.com/pkg/errors" @@ -106,6 +107,7 @@ func (r *RobotAPI) Post() { r.SendBadRequestError(err) return } + robotReq.Visible = true if err := validateRobotReq(r.project, &robotReq); err != nil { r.SendBadRequestError(err) @@ -141,7 +143,13 @@ func (r *RobotAPI) List() { return } - robots, err := r.ctr.ListRobotAccount(r.project.ProjectID) + keywords := make(map[string]interface{}) + keywords["ProjectID"] = r.robot.ProjectID + keywords["Visible"] = true + query := &q.Query{ + Keywords: keywords, + } + robots, err := r.ctr.ListRobotAccount(query) if err != nil { r.SendInternalServerError(errors.Wrap(err, "robot API: list")) return @@ -179,6 +187,10 @@ func (r *RobotAPI) Get() { r.SendNotFoundError(fmt.Errorf("robot API: robot %d not found", id)) return } + if !robot.Visible { + r.SendForbiddenError(fmt.Errorf("robot API: robot %d is invisible", id)) + return + } r.Data["json"] = robot r.ServeJSON() diff --git a/src/pkg/robot/controller.go b/src/pkg/robot/controller.go index 7f793fdbf..5a6565711 100644 --- a/src/pkg/robot/controller.go +++ b/src/pkg/robot/controller.go @@ -6,6 +6,7 @@ import ( "github.com/goharbor/harbor/src/common/token" "github.com/goharbor/harbor/src/common/utils/log" "github.com/goharbor/harbor/src/core/config" + "github.com/goharbor/harbor/src/pkg/q" "github.com/goharbor/harbor/src/pkg/robot/model" "github.com/pkg/errors" "time" @@ -31,7 +32,7 @@ type Controller interface { UpdateRobotAccount(r *model.Robot) error // ListRobotAccount ... - ListRobotAccount(pid int64) ([]*model.Robot, error) + ListRobotAccount(query *q.Query) ([]*model.Robot, error) } // DefaultAPIController ... @@ -66,6 +67,7 @@ func (d *DefaultAPIController) CreateRobotAccount(robotReq *model.RobotCreate) ( Description: robotReq.Description, ProjectID: robotReq.ProjectID, ExpiresAt: expiresAt, + Visible: robotReq.Visible, } id, err := d.manager.CreateRobotAccount(robot) if err != nil { @@ -110,6 +112,6 @@ func (d *DefaultAPIController) UpdateRobotAccount(r *model.Robot) error { } // ListRobotAccount ... -func (d *DefaultAPIController) ListRobotAccount(pid int64) ([]*model.Robot, error) { - return d.manager.ListRobotAccount(pid) +func (d *DefaultAPIController) ListRobotAccount(query *q.Query) ([]*model.Robot, error) { + return d.manager.ListRobotAccount(query) } diff --git a/src/pkg/robot/controller_test.go b/src/pkg/robot/controller_test.go index 6557942bd..6b6fdd70a 100644 --- a/src/pkg/robot/controller_test.go +++ b/src/pkg/robot/controller_test.go @@ -5,6 +5,7 @@ import ( "github.com/goharbor/harbor/src/common/rbac" "github.com/goharbor/harbor/src/common/utils/test" core_cfg "github.com/goharbor/harbor/src/core/config" + "github.com/goharbor/harbor/src/pkg/q" "github.com/goharbor/harbor/src/pkg/robot/model" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -79,7 +80,12 @@ func (s *ControllerTestSuite) TestRobotAccount() { r2, _ := s.ctr.CreateRobotAccount(robot2) s.robotID = r2.ID - robots, err := s.ctr.ListRobotAccount(int64(1)) + keywords := make(map[string]interface{}) + keywords["ProjectID"] = int64(1) + query := &q.Query{ + Keywords: keywords, + } + robots, err := s.ctr.ListRobotAccount(query) s.require.Nil(err) s.require.Equal(len(robots), 2) s.require.Equal(robots[1].Name, common.RobotPrefix+"robot2") @@ -87,7 +93,7 @@ func (s *ControllerTestSuite) TestRobotAccount() { err = s.ctr.DeleteRobotAccount(robot.ID) s.require.Nil(err) - robots, err = s.ctr.ListRobotAccount(int64(1)) + robots, err = s.ctr.ListRobotAccount(query) s.require.Equal(len(robots), 1) } diff --git a/src/pkg/robot/manager.go b/src/pkg/robot/manager.go index 57a86b7e1..9a435e1f3 100644 --- a/src/pkg/robot/manager.go +++ b/src/pkg/robot/manager.go @@ -26,7 +26,7 @@ type Manager interface { UpdateRobotAccount(m *model.Robot) error // ListRobotAccount ... - ListRobotAccount(pid int64) ([]*model.Robot, error) + ListRobotAccount(query *q.Query) ([]*model.Robot, error) } type defaultRobotManager struct { @@ -61,11 +61,6 @@ func (drm *defaultRobotManager) UpdateRobotAccount(r *model.Robot) error { } // ListRobotAccount ... -func (drm *defaultRobotManager) ListRobotAccount(pid int64) ([]*model.Robot, error) { - keywords := make(map[string]interface{}) - keywords["ProjectID"] = pid - query := q.Query{ - Keywords: keywords, - } - return drm.dao.ListRobotAccounts(&query) +func (drm *defaultRobotManager) ListRobotAccount(query *q.Query) ([]*model.Robot, error) { + return drm.dao.ListRobotAccounts(query) } diff --git a/src/pkg/robot/manager_test.go b/src/pkg/robot/manager_test.go index fad225969..e1bd1fd06 100644 --- a/src/pkg/robot/manager_test.go +++ b/src/pkg/robot/manager_test.go @@ -132,7 +132,12 @@ func (m *managerTestingSuite) ListRobotAccount() { ExpiresAt: 54321, }}, nil) - rs, err := Mgr.ListRobotAccount(int64(1)) + keywords := make(map[string]interface{}) + keywords["ProjectID"] = int64(1) + query := &q.Query{ + Keywords: keywords, + } + rs, err := Mgr.ListRobotAccount(query) m.mockRobotDao.AssertCalled(m.t, "ListRobotAccount", mock.Anything) m.require.Nil(err) m.assert.Equal(len(rs), 2) diff --git a/src/pkg/robot/model/robot.go b/src/pkg/robot/model/robot.go index a83a6f13a..db911f11c 100644 --- a/src/pkg/robot/model/robot.go +++ b/src/pkg/robot/model/robot.go @@ -24,6 +24,7 @@ type Robot struct { ProjectID int64 `orm:"column(project_id)" json:"project_id"` ExpiresAt int64 `orm:"column(expiresat)" json:"expires_at"` Disabled bool `orm:"column(disabled)" json:"disabled"` + Visible bool `orm:"column(visible)" json:"-"` CreationTime time.Time `orm:"column(creation_time);auto_now_add" json:"creation_time"` UpdateTime time.Time `orm:"column(update_time);auto_now" json:"update_time"` } @@ -48,6 +49,7 @@ type RobotCreate struct { ProjectID int64 `json:"pid"` Description string `json:"description"` Disabled bool `json:"disabled"` + Visible bool `json:"-"` Access []*rbac.Policy `json:"access"` } diff --git a/src/pkg/scan/api/scan/base_controller_test.go b/src/pkg/scan/api/scan/base_controller_test.go index 932793f10..5d3c87d35 100644 --- a/src/pkg/scan/api/scan/base_controller_test.go +++ b/src/pkg/scan/api/scan/base_controller_test.go @@ -527,8 +527,8 @@ func (mrc *MockRobotController) UpdateRobotAccount(r *model.Robot) error { } // ListRobotAccount ... -func (mrc *MockRobotController) ListRobotAccount(pid int64) ([]*model.Robot, error) { - args := mrc.Called(pid) +func (mrc *MockRobotController) ListRobotAccount(query *q.Query) ([]*model.Robot, error) { + args := mrc.Called(query) if args.Get(0) == nil { return nil, args.Error(1) }