mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-25 18:18:04 +01:00
Add verification that robot account duration is not 0 (#19829)
Signed-off-by: Yang Jiao <yang.jiao@broadcom.com>
This commit is contained in:
parent
8c0f177299
commit
eb125419cc
@ -4719,7 +4719,7 @@ paths:
|
|||||||
summary: Get job log by job id
|
summary: Get job log by job id
|
||||||
description: Get job log by job id, it is only used by administrator
|
description: Get job log by job id, it is only used by administrator
|
||||||
produces:
|
produces:
|
||||||
- text/plain
|
- text/plain
|
||||||
tags:
|
tags:
|
||||||
- jobservice
|
- jobservice
|
||||||
parameters:
|
parameters:
|
||||||
@ -6071,7 +6071,7 @@ paths:
|
|||||||
description: Specify whether the dangerous Artifact are included inside summary information
|
description: Specify whether the dangerous Artifact are included inside summary information
|
||||||
type: boolean
|
type: boolean
|
||||||
required: false
|
required: false
|
||||||
default: false
|
default: false
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: Success
|
description: Success
|
||||||
@ -6090,15 +6090,15 @@ paths:
|
|||||||
get:
|
get:
|
||||||
summary: Get the vulnerability list.
|
summary: Get the vulnerability list.
|
||||||
description: |
|
description: |
|
||||||
Get the vulnerability list. use q to pass the query condition,
|
Get the vulnerability list. use q to pass the query condition,
|
||||||
supported conditions:
|
supported conditions:
|
||||||
cve_id(exact match)
|
cve_id(exact match)
|
||||||
cvss_score_v3(range condition)
|
cvss_score_v3(range condition)
|
||||||
severity(exact match)
|
severity(exact match)
|
||||||
repository_name(exact match)
|
repository_name(exact match)
|
||||||
project_id(exact match)
|
project_id(exact match)
|
||||||
package(exact match)
|
package(exact match)
|
||||||
tag(exact match)
|
tag(exact match)
|
||||||
digest(exact match)
|
digest(exact match)
|
||||||
tags:
|
tags:
|
||||||
- securityhub
|
- securityhub
|
||||||
@ -7656,8 +7656,9 @@ definitions:
|
|||||||
description: The level of the robot, project or system
|
description: The level of the robot, project or system
|
||||||
duration:
|
duration:
|
||||||
type: integer
|
type: integer
|
||||||
|
x-nullable: true
|
||||||
format: int64
|
format: int64
|
||||||
description: The duration of the robot in days
|
description: The duration of the robot in days, duration must be either -1(Never) or a positive integer
|
||||||
editable:
|
editable:
|
||||||
type: boolean
|
type: boolean
|
||||||
x-omitempty: false
|
x-omitempty: false
|
||||||
@ -7704,7 +7705,7 @@ definitions:
|
|||||||
duration:
|
duration:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
description: The duration of the robot in days
|
description: The duration of the robot in days, duration must be either -1(Never) or a positive integer
|
||||||
permissions:
|
permissions:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
@ -7994,7 +7995,7 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
description: |
|
description: |
|
||||||
The schedule type. The valid values are 'Hourly', 'Daily', 'Weekly', 'Custom', 'Manual', 'None' and 'Schedule'.
|
The schedule type. The valid values are 'Hourly', 'Daily', 'Weekly', 'Custom', 'Manual', 'None' and 'Schedule'.
|
||||||
'Manual' means to trigger it right away, 'Schedule' means to trigger it by a specified cron schedule and
|
'Manual' means to trigger it right away, 'Schedule' means to trigger it by a specified cron schedule and
|
||||||
'None' means to cancel the schedule.
|
'None' means to cancel the schedule.
|
||||||
enum:
|
enum:
|
||||||
- Hourly
|
- Hourly
|
||||||
@ -9813,12 +9814,12 @@ definitions:
|
|||||||
type: object
|
type: object
|
||||||
description: the dangerous CVE information
|
description: the dangerous CVE information
|
||||||
properties:
|
properties:
|
||||||
cve_id:
|
cve_id:
|
||||||
type: string
|
type: string
|
||||||
description: the cve id
|
description: the cve id
|
||||||
severity:
|
severity:
|
||||||
type: string
|
type: string
|
||||||
description: the severity of the CVE
|
description: the severity of the CVE
|
||||||
cvss_score_v3:
|
cvss_score_v3:
|
||||||
type: number
|
type: number
|
||||||
format: float64
|
format: float64
|
||||||
@ -9828,7 +9829,7 @@ definitions:
|
|||||||
description: the description of the CVE
|
description: the description of the CVE
|
||||||
package:
|
package:
|
||||||
type: string
|
type: string
|
||||||
description: the package of the CVE
|
description: the package of the CVE
|
||||||
version:
|
version:
|
||||||
type: string
|
type: string
|
||||||
description: the version of the package
|
description: the version of the package
|
||||||
@ -9836,14 +9837,14 @@ definitions:
|
|||||||
type: object
|
type: object
|
||||||
description: the dangerous artifact information
|
description: the dangerous artifact information
|
||||||
properties:
|
properties:
|
||||||
project_id:
|
project_id:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
description: the project id of the artifact
|
description: the project id of the artifact
|
||||||
repository_name:
|
repository_name:
|
||||||
type: string
|
type: string
|
||||||
description: the repository name of the artifact
|
description: the repository name of the artifact
|
||||||
digest:
|
digest:
|
||||||
type: string
|
type: string
|
||||||
description: the digest of the artifact
|
description: the digest of the artifact
|
||||||
critical_cnt:
|
critical_cnt:
|
||||||
@ -9903,6 +9904,6 @@ definitions:
|
|||||||
description: The description of the vulnerability
|
description: The description of the vulnerability
|
||||||
links:
|
links:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
description: Links of the vulnerability
|
description: Links of the vulnerability
|
||||||
|
@ -102,10 +102,6 @@ func (d *controller) Create(ctx context.Context, r *Robot) (int64, string, error
|
|||||||
var expiresAt int64
|
var expiresAt int64
|
||||||
if r.Duration == -1 {
|
if r.Duration == -1 {
|
||||||
expiresAt = -1
|
expiresAt = -1
|
||||||
} else if r.Duration == 0 {
|
|
||||||
// system default robot duration
|
|
||||||
r.Duration = int64(config.RobotTokenDuration(ctx))
|
|
||||||
expiresAt = time.Now().AddDate(0, 0, config.RobotTokenDuration(ctx)).Unix()
|
|
||||||
} else {
|
} else {
|
||||||
durationStr := strconv.FormatInt(r.Duration, 10)
|
durationStr := strconv.FormatInt(r.Duration, 10)
|
||||||
duration, err := strconv.Atoi(durationStr)
|
duration, err := strconv.Atoi(durationStr)
|
||||||
|
@ -925,6 +925,7 @@ func (bc *basicController) makeRobotAccount(ctx context.Context, projectID int64
|
|||||||
Name: fmt.Sprintf("%s-%s-%s", scannerPrefix, registration.Name, UUID),
|
Name: fmt.Sprintf("%s-%s-%s", scannerPrefix, registration.Name, UUID),
|
||||||
Description: "for scan",
|
Description: "for scan",
|
||||||
ProjectID: projectID,
|
ProjectID: projectID,
|
||||||
|
Duration: -1,
|
||||||
},
|
},
|
||||||
Level: robot.LEVELPROJECT,
|
Level: robot.LEVELPROJECT,
|
||||||
Permissions: []*robot.Permission{
|
Permissions: []*robot.Permission{
|
||||||
|
@ -199,6 +199,7 @@ func (suite *ControllerTestSuite) SetupSuite() {
|
|||||||
Name: rname,
|
Name: rname,
|
||||||
Description: "for scan",
|
Description: "for scan",
|
||||||
ProjectID: suite.artifact.ProjectID,
|
ProjectID: suite.artifact.ProjectID,
|
||||||
|
Duration: -1,
|
||||||
},
|
},
|
||||||
Level: robot.LEVELPROJECT,
|
Level: robot.LEVELPROJECT,
|
||||||
Permissions: []*robot.Permission{
|
Permissions: []*robot.Permission{
|
||||||
@ -229,6 +230,7 @@ func (suite *ControllerTestSuite) SetupSuite() {
|
|||||||
Secret: "robot-account",
|
Secret: "robot-account",
|
||||||
Description: "for scan",
|
Description: "for scan",
|
||||||
ProjectID: suite.artifact.ProjectID,
|
ProjectID: suite.artifact.ProjectID,
|
||||||
|
Duration: -1,
|
||||||
},
|
},
|
||||||
Level: "project",
|
Level: "project",
|
||||||
}, nil)
|
}, nil)
|
||||||
@ -336,7 +338,7 @@ func (suite *ControllerTestSuite) TestScanControllerScan() {
|
|||||||
mock.OnAnything(suite.execMgr, "Create").Return(int64(1), nil).Once()
|
mock.OnAnything(suite.execMgr, "Create").Return(int64(1), nil).Once()
|
||||||
mock.OnAnything(suite.taskMgr, "Create").Return(int64(1), nil).Once()
|
mock.OnAnything(suite.taskMgr, "Create").Return(int64(1), nil).Once()
|
||||||
|
|
||||||
ctx := orm.NewContext(nil, &ormtesting.FakeOrmer{})
|
ctx := orm.NewContext(context.TODO(), &ormtesting.FakeOrmer{})
|
||||||
|
|
||||||
suite.Require().NoError(suite.c.Scan(ctx, suite.artifact))
|
suite.Require().NoError(suite.c.Scan(ctx, suite.artifact))
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ func (r *Robot) ToSwagger() *models.Robot {
|
|||||||
Name: r.Name,
|
Name: r.Name,
|
||||||
Description: r.Description,
|
Description: r.Description,
|
||||||
ExpiresAt: r.ExpiresAt,
|
ExpiresAt: r.ExpiresAt,
|
||||||
Duration: r.Duration,
|
Duration: &r.Duration,
|
||||||
Level: r.Level,
|
Level: r.Level,
|
||||||
Disable: r.Disabled,
|
Disable: r.Disabled,
|
||||||
Editable: r.Editable,
|
Editable: r.Editable,
|
||||||
|
@ -29,7 +29,6 @@ import (
|
|||||||
"github.com/goharbor/harbor/src/common/utils"
|
"github.com/goharbor/harbor/src/common/utils"
|
||||||
"github.com/goharbor/harbor/src/controller/robot"
|
"github.com/goharbor/harbor/src/controller/robot"
|
||||||
"github.com/goharbor/harbor/src/lib"
|
"github.com/goharbor/harbor/src/lib"
|
||||||
"github.com/goharbor/harbor/src/lib/config"
|
|
||||||
"github.com/goharbor/harbor/src/lib/errors"
|
"github.com/goharbor/harbor/src/lib/errors"
|
||||||
"github.com/goharbor/harbor/src/lib/log"
|
"github.com/goharbor/harbor/src/lib/log"
|
||||||
"github.com/goharbor/harbor/src/pkg/permission/types"
|
"github.com/goharbor/harbor/src/pkg/permission/types"
|
||||||
@ -276,7 +275,7 @@ func (rAPI *robotAPI) requireAccess(ctx context.Context, level string, projectID
|
|||||||
// more validation
|
// more validation
|
||||||
func (rAPI *robotAPI) validate(d int64, level string, permissions []*models.RobotPermission) error {
|
func (rAPI *robotAPI) validate(d int64, level string, permissions []*models.RobotPermission) error {
|
||||||
if !isValidDuration(d) {
|
if !isValidDuration(d) {
|
||||||
return errors.New(nil).WithMessage("bad request error duration input: %d", d).WithCode(errors.BadRequestCode)
|
return errors.New(nil).WithMessage("bad request error duration input: %d, duration must be either -1(Never) or a positive integer", d).WithCode(errors.BadRequestCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isValidLevel(level) {
|
if !isValidLevel(level) {
|
||||||
@ -323,7 +322,10 @@ func (rAPI *robotAPI) validate(d int64, level string, permissions []*models.Robo
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (rAPI *robotAPI) updateV2Robot(ctx context.Context, params operation.UpdateRobotParams, r *robot.Robot) error {
|
func (rAPI *robotAPI) updateV2Robot(ctx context.Context, params operation.UpdateRobotParams, r *robot.Robot) error {
|
||||||
if err := rAPI.validate(params.Robot.Duration, params.Robot.Level, params.Robot.Permissions); err != nil {
|
if params.Robot.Duration == nil {
|
||||||
|
params.Robot.Duration = &r.Duration
|
||||||
|
}
|
||||||
|
if err := rAPI.validate(*params.Robot.Duration, params.Robot.Level, params.Robot.Permissions); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if r.Level != robot.LEVELSYSTEM {
|
if r.Level != robot.LEVELSYSTEM {
|
||||||
@ -342,15 +344,12 @@ func (rAPI *robotAPI) updateV2Robot(ctx context.Context, params operation.Update
|
|||||||
return errors.BadRequestError(nil).WithMessage("cannot update the level or name of robot")
|
return errors.BadRequestError(nil).WithMessage("cannot update the level or name of robot")
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.Duration != params.Robot.Duration {
|
if r.Duration != *params.Robot.Duration {
|
||||||
r.Duration = params.Robot.Duration
|
r.Duration = *params.Robot.Duration
|
||||||
if params.Robot.Duration == -1 {
|
if *params.Robot.Duration == -1 {
|
||||||
r.ExpiresAt = -1
|
r.ExpiresAt = -1
|
||||||
} else if params.Robot.Duration == 0 {
|
|
||||||
r.Duration = int64(config.RobotTokenDuration(ctx))
|
|
||||||
r.ExpiresAt = r.CreationTime.AddDate(0, 0, config.RobotTokenDuration(ctx)).Unix()
|
|
||||||
} else {
|
} else {
|
||||||
r.ExpiresAt = r.CreationTime.AddDate(0, 0, int(params.Robot.Duration)).Unix()
|
r.ExpiresAt = r.CreationTime.AddDate(0, 0, int(*params.Robot.Duration)).Unix()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,7 +374,7 @@ func isValidLevel(l string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func isValidDuration(d int64) bool {
|
func isValidDuration(d int64) bool {
|
||||||
return d >= int64(-1) && d < math.MaxInt32
|
return d >= int64(-1) && d != 0 && d < math.MaxInt32
|
||||||
}
|
}
|
||||||
|
|
||||||
// validateName validates the robot name, especially '+' cannot be a valid character
|
// validateName validates the robot name, especially '+' cannot be a valid character
|
||||||
|
@ -47,7 +47,7 @@ func TestValidDuration(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{"duration 0",
|
{"duration 0",
|
||||||
0,
|
0,
|
||||||
true,
|
false,
|
||||||
},
|
},
|
||||||
{"duration 1",
|
{"duration 1",
|
||||||
1,
|
1,
|
||||||
|
Loading…
Reference in New Issue
Block a user