Return bad request if audit log retention hour > 240000 hour (#17217)

Cap the retention hour to 240000 hour
  Fixes #17198

Signed-off-by: stonezdj <stonezdj@gmail.com>
This commit is contained in:
stonezdj(Daojun Zhang) 2022-07-22 15:14:10 +08:00 committed by GitHub
parent 8e876d847c
commit 712419778a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 60 additions and 8 deletions

View File

@ -215,4 +215,6 @@ const (
AuditLogForwardEndpoint = "audit_log_forward_endpoint"
// SkipAuditLogDatabase skip to log audit log in database
SkipAuditLogDatabase = "skip_audit_log_database"
// MaxAuditRetentionHour allowed in audit log purge
MaxAuditRetentionHour = 240000
)

View File

@ -102,6 +102,10 @@ func (j *Job) Run(ctx job.Context, params job.Parameters) error {
logger.Infof("quit purge job, retentionHour:%v ", j.retentionHour)
return nil
}
// cap the retentionHour
if j.retentionHour > common.MaxAuditRetentionHour {
j.retentionHour = common.MaxAuditRetentionHour
}
n, err := j.auditMgr.Purge(ormCtx, j.retentionHour, j.includeOperations, j.dryRun)
if err != nil {
logger.Errorf("failed to purge audit log, error: %v", err)

View File

@ -81,12 +81,31 @@ func verifyCreateRequest(params purge.CreatePurgeScheduleParams) error {
if _, exist := params.Schedule.Parameters[common.PurgeAuditRetentionHour]; !exist {
return errors.BadRequestError(fmt.Errorf("audit_retention_hour should provide"))
}
if _, err := retentionHour(params.Schedule.Parameters); err != nil {
return err
}
if _, exist := params.Schedule.Parameters[common.PurgeAuditIncludeOperations]; !exist {
return errors.BadRequestError(fmt.Errorf("include_operations should provide"))
}
return nil
}
func retentionHour(m map[string]interface{}) (int, error) {
if ret, ok := m[common.PurgeAuditRetentionHour]; ok {
if rh, ok := ret.(json.Number); ok {
ret, err := rh.Int64()
if err != nil {
return 0, errors.BadRequestError(fmt.Errorf("audit_retention_hour should be integer format"))
}
if int(ret) > common.MaxAuditRetentionHour {
return 0, errors.BadRequestError(fmt.Errorf("audit_retention_hour should be less than %d", common.MaxAuditRetentionHour))
}
return int(ret), nil
}
}
return 0, nil
}
func (p *purgeAPI) kick(ctx context.Context, vendorType string, scheType string, cron string, parameters map[string]interface{}) (int64, error) {
if parameters == nil {
parameters = make(map[string]interface{})
@ -103,15 +122,11 @@ func (p *purgeAPI) kick(ctx context.Context, vendorType string, scheType string,
if includeOperations, ok := parameters[common.PurgeAuditIncludeOperations].(string); ok {
policy.IncludeOperations = includeOperations
}
if retentionHour, ok := parameters[common.PurgeAuditRetentionHour]; ok {
if rh, ok := retentionHour.(json.Number); ok {
ret, err := rh.Int64()
if err != nil {
return 0, errors.BadRequestError(fmt.Errorf("failed to convert audit_retention_hour, error: %v", err))
}
policy.RetentionHour = int(ret)
}
retHour, err := retentionHour(parameters)
if err != nil {
return 0, err
}
policy.RetentionHour = retHour
switch scheType {
case ScheduleManual:
@ -290,6 +305,9 @@ func verifyUpdateRequest(params operation.UpdatePurgeScheduleParams) error {
if _, exist := params.Schedule.Parameters[common.PurgeAuditRetentionHour]; !exist {
return errors.BadRequestError(fmt.Errorf("audit_retention_hour should provide"))
}
if _, err := retentionHour(params.Schedule.Parameters); err != nil {
return err
}
if _, exist := params.Schedule.Parameters[common.PurgeAuditIncludeOperations]; !exist {
return errors.BadRequestError(fmt.Errorf("include_operations should provide"))
}

View File

@ -15,11 +15,13 @@
package handler
import (
"fmt"
"testing"
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/server/v2.0/models"
"github.com/goharbor/harbor/src/server/v2.0/restapi/operations/purge"
"github.com/stretchr/testify/assert"
)
func Test_verifyUpdateRequest(t *testing.T) {
@ -68,3 +70,29 @@ func Test_verifyCreateRequest(t *testing.T) {
})
}
}
func Test_checkRetentionHour(t *testing.T) {
type args struct {
m map[string]interface{}
}
tests := []struct {
name string
args args
want int
wantErr assert.ErrorAssertionFunc
}{
{"normal", args{map[string]interface{}{common.PurgeAuditRetentionHour: 24}}, 24, func(t assert.TestingT, err error, i ...interface{}) bool { return false }},
{"overflow", args{map[string]interface{}{common.PurgeAuditRetentionHour: 250000}}, 0, func(t assert.TestingT, err error, i ...interface{}) bool { return true }},
{"equal", args{map[string]interface{}{common.PurgeAuditRetentionHour: 240000}}, 240000, func(t assert.TestingT, err error, i ...interface{}) bool { return false }},
{"wrong type", args{map[string]interface{}{common.PurgeAuditRetentionHour: "wrong type"}}, 0, func(t assert.TestingT, err error, i ...interface{}) bool { return true }},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := retentionHour(tt.args.m)
if !tt.wantErr(t, err, fmt.Sprintf("retentionHour(%v)", tt.args.m)) {
return
}
assert.Equalf(t, tt.want, got, "retentionHour(%v)", tt.args.m)
})
}
}