diff --git a/src/common/const.go b/src/common/const.go index 07c127cb3..ff65d0f15 100755 --- a/src/common/const.go +++ b/src/common/const.go @@ -223,4 +223,7 @@ const ( // SessionTimeout defines the web session timeout SessionTimeout = "session_timeout" + + // UIMaxLengthLimitedOfNumber is the max length that UI limited for type number + UIMaxLengthLimitedOfNumber = 10 ) diff --git a/src/controller/config/controller.go b/src/controller/config/controller.go index 1924fc647..196ae960f 100644 --- a/src/controller/config/controller.go +++ b/src/controller/config/controller.go @@ -134,7 +134,16 @@ func (c *controller) validateCfg(ctx context.Context, cfgs map[string]interface{ return errors.BadRequestError(err) } - return verifySkipAuditLogCfg(ctx, cfgs, mgr) + // verify the skip audit log related cfgs + if err = verifySkipAuditLogCfg(ctx, cfgs, mgr); err != nil { + return err + } + // verify the value length related cfgs + if err = verifyValueLengthCfg(ctx, cfgs); err != nil { + return err + } + + return nil } func verifySkipAuditLogCfg(ctx context.Context, cfgs map[string]interface{}, mgr config.Manager) error { @@ -159,6 +168,52 @@ func verifySkipAuditLogCfg(ctx context.Context, cfgs map[string]interface{}, mgr return nil } +// verifyValueLengthCfg verifies the cfgs which need to check the value max length to align with frontend. +func verifyValueLengthCfg(ctx context.Context, cfgs map[string]interface{}) error { + maxValue := maxValueLimitedByLength(common.UIMaxLengthLimitedOfNumber) + validateCfgs := []string{ + common.TokenExpiration, + common.RobotTokenDuration, + common.SessionTimeout, + } + + for _, c := range validateCfgs { + if v, exist := cfgs[c]; exist { + // the cfgs is unmarshal from json string, the number type will be float64 + if vf, ok := v.(float64); ok { + if vf <= 0 { + return errors.BadRequestError(nil).WithMessage("the %s value must be positive", c) + } + + if int64(vf) > maxValue { + return errors.BadRequestError(nil).WithMessage(fmt.Sprintf("the %s value is over the limit value: %d", c, maxValue)) + } + } + } + } + + return nil +} + +// maxValueLimitedByLength returns the max value can be equaled limited by the fixed length. +func maxValueLimitedByLength(length int) int64 { + // return -1 if length is negative + if length <= 0 { + return -1 + } + + // the sum value + var value int64 + // the times for multiple, should *10 for every time + times := 1 + for i := 0; i < length; i++ { + value = value + int64(9*times) + times = times * 10 + } + + return value +} + // ScanAllPolicy is represent the json request and object for scan all policy // Only for migrating from the legacy schedule. type ScanAllPolicy struct { diff --git a/src/controller/config/controller_test.go b/src/controller/config/controller_test.go index 3e910b447..d3f4ed9e6 100644 --- a/src/controller/config/controller_test.go +++ b/src/controller/config/controller_test.go @@ -63,3 +63,60 @@ func Test_verifySkipAuditLogCfg(t *testing.T) { }) } } + +func Test_maxValueLimitedByLength(t *testing.T) { + type args struct { + length int + } + tests := []struct { + name string + args args + want int64 + }{ + {name: "negative length should return -1", args: args{0}, want: -1}, + {name: "input length 1 should return 9", args: args{1}, want: 9}, + {name: "input length 5 should return 99999", args: args{5}, want: 99999}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := maxValueLimitedByLength(tt.args.length); got != tt.want { + t.Errorf("maxValueLimitedByLength() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_verifyValueLengthCfg(t *testing.T) { + type args struct { + ctx context.Context + cfgs map[string]interface{} + } + tests := []struct { + name string + args args + wantErr bool + }{ + {name: "valid config", args: args{context.TODO(), map[string]interface{}{ + common.TokenExpiration: float64(100), + common.RobotTokenDuration: float64(100), + common.SessionTimeout: float64(100), + }}, wantErr: false}, + {name: "invalid config with negative value", args: args{context.TODO(), map[string]interface{}{ + common.TokenExpiration: float64(-1), + common.RobotTokenDuration: float64(100), + common.SessionTimeout: float64(100), + }}, wantErr: true}, + {name: "invalid config with value over length limit", args: args{context.TODO(), map[string]interface{}{ + common.TokenExpiration: float64(100), + common.RobotTokenDuration: float64(100000000000000000), + common.SessionTimeout: float64(100), + }}, wantErr: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := verifyValueLengthCfg(tt.args.ctx, tt.args.cfgs); (err != nil) != tt.wantErr { + t.Errorf("verifyMaxLengthCfg() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +}