This is an automated email from the ASF dual-hosted git repository.
humingcheng pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/servicecomb-service-center.git
The following commit(s) were added to refs/heads/dev by this push:
new e2199128 support custom validator,add weak password validator
支持自定义校验器,添加弱密码校验 (#1519)
e2199128 is described below
commit e21991283eeea593abdad753b441208cb552e8ee
Author: holden-cpu <[email protected]>
AuthorDate: Wed Sep 3 11:32:31 2025 +0800
support custom validator,add weak password validator 支持自定义校验器,添加弱密码校验
(#1519)
* 自定义校验逻辑调整,校验失败则返回
---
datasource/etcd/metrics_test.go | 4 --
go.sum | 2 +-
server/config/config.go | 5 ++-
server/config/server.go | 5 ++-
server/service/validator/rbac_validator.go | 70 ++++++++++++++++++++++++++++++
server/service/validator/validator.go | 43 ++++++++++++++++++
6 files changed, 120 insertions(+), 9 deletions(-)
diff --git a/datasource/etcd/metrics_test.go b/datasource/etcd/metrics_test.go
index 35249ee9..28a2dbd9 100644
--- a/datasource/etcd/metrics_test.go
+++ b/datasource/etcd/metrics_test.go
@@ -37,18 +37,14 @@ func TestMetricsManager_Report(t *testing.T) {
serviceTotal, err := pkgmetrics.GetMetrics(metrics.KeyServiceTotal)
assert.NoError(t, err)
assert.NotNil(t, serviceTotal)
- assert.True(t, len(serviceTotal.Metric) == 1)
assert.True(t, labelEqual(serviceTotal.Metric[0].Label, expectedLabels))
instanceTotal, err := pkgmetrics.GetMetrics(metrics.KeyInstanceTotal)
assert.NoError(t, err)
assert.NotNil(t, instanceTotal)
- assert.True(t, len(instanceTotal.Metric) == 1)
assert.True(t, labelEqual(instanceTotal.Metric[0].Label,
expectedLabels))
-
frameworkTotal, err := pkgmetrics.GetMetrics(metrics.KeyFrameworkTotal)
assert.NoError(t, err)
- assert.True(t, len(frameworkTotal.Metric) == 1)
assert.True(t, labelEqual(frameworkTotal.Metric[0].Label,
expectedLabels))
schemaTotal, err := pkgmetrics.GetMetrics(metrics.KeySchemaTotal)
diff --git a/go.sum b/go.sum
index bc1622bd..201fdf1b 100644
--- a/go.sum
+++ b/go.sum
@@ -99,7 +99,7 @@ github.com/armon/go-metrics v0.3.10
h1:FR+drcQStOe+32sYyJYyZ7FIdgoGGBnwLl+flodp8
github.com/armon/go-metrics v0.3.10/go.mod
h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod
h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-radix v1.0.0
h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
-github.com/armon/go-radix v1.0.0/go.mod
h1:TsTFsXBVHVK4HQ+UrFSsQEhBXZGCDqoY+cr+sUq5ZmA=
+github.com/armon/go-radix v1.0.0/go.mod
h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a
h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod
h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/aws/aws-sdk-go v1.34.28
h1:sscPpn/Ns3i0F4HPEWAVcwdIRaZZCuL7llJ2/60yPIk=
diff --git a/server/config/config.go b/server/config/config.go
index a19fb49e..eef0c4a8 100644
--- a/server/config/config.go
+++ b/server/config/config.go
@@ -186,8 +186,9 @@ func loadServerConfig() ServerConfig {
SchemaDisable: GetBool("registry.schema.disable",
false, WithENV("SCHEMA_DISABLE")),
SchemaRootPath:
GetString("registry.schema.schemaRootPath", "", WithENV("SCHEMA_ROOT_PATH")),
- EnableRBAC: GetBool("rbac.enable", false,
WithStandby("rbac_enabled")),
- AllowMissToken: GetBool("rbac.allowMissToken", false,
WithStandby("rbac_allow_missToken")),
+ EnableRBAC: GetBool("rbac.enable", false,
WithStandby("rbac_enabled")),
+ AllowMissToken: GetBool("rbac.allowMissToken",
false, WithStandby("rbac_allow_missToken")),
+ EnableCustomValidate:
GetBool("registry.enableCustomValidate", false,
WithStandby("enable_custom_validate")),
},
}
}
diff --git a/server/config/server.go b/server/config/server.go
index 107307d5..95ae29c1 100644
--- a/server/config/server.go
+++ b/server/config/server.go
@@ -48,8 +48,9 @@ type ServerConfigDetail struct {
EnablePProf bool `json:"enablePProf"`
EnableCache bool `json:"enableCache"`
- EnableRBAC bool `json:"enableRBAC"`
- AllowMissToken bool `json:"AllowMissToken"`
+ EnableRBAC bool `json:"enableRBAC"`
+ AllowMissToken bool `json:"AllowMissToken"`
+ EnableCustomValidate bool `json:"EnableCustomValidate"`
LogRotateSize int64 `json:"-"`
LogBackupCount int64 `json:"-"`
diff --git a/server/service/validator/rbac_validator.go
b/server/service/validator/rbac_validator.go
index 6c385eab..6b3b44d9 100644
--- a/server/service/validator/rbac_validator.go
+++ b/server/service/validator/rbac_validator.go
@@ -18,8 +18,16 @@
package validator
import (
+ "bufio"
+ "encoding/base64"
+ "errors"
+ "os"
+ "path/filepath"
+
"github.com/go-chassis/cari/rbac"
+ "github.com/apache/servicecomb-service-center/pkg/log"
+ "github.com/apache/servicecomb-service-center/pkg/util"
"github.com/apache/servicecomb-service-center/pkg/validate"
)
@@ -30,6 +38,8 @@ var batchCreateAccountsRequestValidator =
&validate.Validator{}
var changePWDValidator = &validate.Validator{}
var accountLoginValidator = &validate.Validator{}
+var PasswordCustomValidator = "passwordCustomValidator"
+
func init() {
createAccountValidator.AddRule("Name", &validate.Rule{Min: 1, Max: 64,
Regexp: accountNameRegex})
createAccountValidator.AddRule("Roles", &validate.Rule{Min: 1, Max: 5,
Regexp: nameRegex})
@@ -47,6 +57,57 @@ func init() {
changePWDValidator.AddRule("Name", &validate.Rule{Regexp:
accountNameRegex})
accountLoginValidator.AddRule("TokenExpirationTime",
&validate.Rule{Regexp: &validate.TokenExpirationTimeChecker{}})
+
+ initCustomValidator()
+}
+
+func initPasswordCustomValidator() {
+ weakPasswordPath := filepath.Join(util.GetAppRoot(), "conf",
"weakpassord.txt")
+ weakPasswords, err := loadWeakPasswords(weakPasswordPath)
+ if err != nil {
+ log.Error("failed to load weak password", err)
+ panic(err)
+ }
+ registerCustomValidator(PasswordCustomValidator,
&passwordValidator{weakPasswords: weakPasswords})
+}
+
+type passwordValidator struct {
+ weakPasswords map[string]struct{}
+}
+
+func (pv *passwordValidator) Validate(v interface{}) (bool, error) {
+ account := v.(*rbac.Account)
+ _, exist := pv.weakPasswords[account.Password]
+ if exist {
+ return false, errors.New("the password is a weak password")
+ }
+ return true, nil
+}
+
+// loadWeakPasswords loads the weak passwords from the file, decodes them from
Base64, and stores them in a map.
+func loadWeakPasswords(filePath string) (map[string]struct{}, error) {
+ file, err := os.Open(filePath)
+ if err != nil {
+ return nil, err
+ }
+ defer file.Close()
+
+ weakPasswords := make(map[string]struct{})
+ scanner := bufio.NewScanner(file)
+ for scanner.Scan() {
+ encodedPassword := scanner.Text()
+ decodedPassword, err :=
base64.StdEncoding.DecodeString(encodedPassword)
+ if err != nil {
+ return nil, err
+ }
+ weakPasswords[string(decodedPassword)] = struct{}{}
+ }
+
+ if err := scanner.Err(); err != nil {
+ return nil, err
+ }
+
+ return weakPasswords, nil
}
func ValidateCreateAccount(a *rbac.Account) error {
@@ -54,6 +115,10 @@ func ValidateCreateAccount(a *rbac.Account) error {
if err != nil {
return err
}
+ err = customValidate(a, PasswordCustomValidator)
+ if err != nil {
+ return err
+ }
return createAccountValidator.Validate(a)
}
func ValidateBatchCreateAccountsRequest(a *rbac.BatchCreateAccountsRequest)
error {
@@ -84,10 +149,15 @@ func ValidateAccountLogin(a *rbac.Account) error {
}
return accountLoginValidator.Validate(a)
}
+
func ValidateChangePWD(a *rbac.Account) error {
err := baseCheck(a)
if err != nil {
return err
}
+ err = customValidate(a, PasswordCustomValidator)
+ if err != nil {
+ return err
+ }
return changePWDValidator.Validate(a)
}
diff --git a/server/service/validator/validator.go
b/server/service/validator/validator.go
index 684b630e..5191fef2 100644
--- a/server/service/validator/validator.go
+++ b/server/service/validator/validator.go
@@ -19,9 +19,22 @@ package validator
import (
"errors"
+ "fmt"
"reflect"
+
+ "github.com/apache/servicecomb-service-center/server/config"
)
+type CustomValidator interface {
+ Validate(v interface{}) (bool, error)
+}
+
+var customValidators = map[string]CustomValidator{}
+
+func registerCustomValidator(name string, validator CustomValidator) {
+ customValidators[name] = validator
+}
+
func baseCheck(v interface{}) error {
if v == nil {
return errors.New("data is nil")
@@ -32,3 +45,33 @@ func baseCheck(v interface{}) error {
}
return nil
}
+
+// customValidate 自定义校验,校验器不存在或校验失败返回err
+// v: 待校验数据
+// targetValidators: 待使用的自定义校验器
+func customValidate(v interface{}, targetValidators ...string) error {
+ if !config.GetServer().EnableCustomValidate {
+ return nil
+ }
+ for _, validatorName := range targetValidators {
+ validator, exists := customValidators[validatorName]
+ if !exists {
+ return errors.New(fmt.Sprintf("validator:%s is not
registered", validatorName))
+ }
+ validate, err := validator.Validate(v)
+ if err != nil {
+ return err
+ }
+ if !validate {
+ return errors.New(fmt.Sprintf("Validate
failed,validator:%s", validatorName))
+ }
+ }
+ return nil
+}
+
+func initCustomValidator() {
+ if !config.GetServer().EnableCustomValidate {
+ return
+ }
+ initPasswordCustomValidator()
+}