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()
+}

Reply via email to