2
0
mirror of https://github.com/acepanel/panel.git synced 2026-02-04 06:47:20 +08:00

feat: 添加密码复杂度验证

This commit is contained in:
耗子
2024-10-17 18:40:27 +08:00
parent 2112e86329
commit b36f7f3085
9 changed files with 73 additions and 11 deletions

View File

@@ -5,5 +5,5 @@ type UpdateConfig struct {
}
type SetRootPassword struct {
Password string `form:"password" json:"password" validate:"required"`
Password string `form:"password" json:"password" validate:"required,password"`
}

View File

@@ -2,7 +2,7 @@ package pureftpd
type Create struct {
Username string `form:"username" json:"username" validate:"required"`
Password string `form:"password" json:"password" validate:"required"`
Password string `form:"password" json:"password" validate:"required,password"`
Path string `form:"path" json:"path" validate:"required"`
}
@@ -12,7 +12,7 @@ type Delete struct {
type ChangePassword struct {
Username string `form:"username" json:"username" validate:"required"`
Password string `form:"password" json:"password" validate:"required"`
Password string `form:"password" json:"password" validate:"required,password"`
}
type UpdatePort struct {

View File

@@ -18,5 +18,5 @@ type Hosts struct {
}
type Password struct {
Password string `form:"password" json:"password" validate:"required"`
Password string `form:"password" json:"password" validate:"required,password"`
}

View File

@@ -251,11 +251,6 @@ func (s *Service) UpdateRootPassword(w http.ResponseWriter, r *http.Request) {
return
}
if !regexp.MustCompile(`^[a-zA-Z0-9·~!@#$%^&*()_+-=\[\]{};:'",./<>?]{6,20}$`).MatchString(req.Password) {
service.Error(w, http.StatusUnprocessableEntity, "密码必须为 6-20 位字母、数字或特殊字符")
return
}
req.Password = strings.ReplaceAll(req.Password, `'`, `\'`)
if _, err = shell.Execf(`yes '%s' | passwd root`, req.Password); err != nil {
service.Error(w, http.StatusInternalServerError, "%v", err)

View File

@@ -8,7 +8,7 @@ type PanelSetting struct {
WebsitePath string `json:"website_path" validate:"required"`
BackupPath string `json:"backup_path" validate:"required"`
Username string `json:"username" validate:"required"`
Password string `json:"password"`
Password string `json:"password" validate:"password"`
Email string `json:"email" validate:"required"`
Port int `json:"port" validate:"required,number,gte=1,lte=65535"`
HTTPS bool `json:"https"`

View File

@@ -17,7 +17,7 @@ type WebsiteCreate struct {
DBType string `form:"db_type" json:"db_type"`
DBName string `form:"db_name" json:"db_name"`
DBUser string `form:"db_user" json:"db_user"`
DBPassword string `form:"db_password" json:"db_password"`
DBPassword string `form:"db_password" json:"db_password" validate:"password"`
}
type WebsiteDelete struct {

View File

@@ -0,0 +1,50 @@
package rule
import (
"unicode"
"github.com/go-playground/validator/v10"
)
type Password struct{}
func NewPassword() *Password {
return &Password{}
}
// Password 密码复杂度校验
func (r *Password) Password(fl validator.FieldLevel) bool {
password := fl.Field().String()
// 不对空密码进行校验,有需要可以使用 required 标签
if password == "" {
return true
}
var hasUpper, hasLower, hasNumber, hasSpecial bool
if len(password) < 8 || len(password) > 20 {
return false
}
for _, char := range password {
switch {
case unicode.IsUpper(char):
hasUpper = true
case unicode.IsLower(char):
hasLower = true
case unicode.IsNumber(char):
hasNumber = true
case unicode.IsPunct(char) || unicode.IsSymbol(char):
hasSpecial = true
}
}
// 至少包含两类字符组合
valid := (hasUpper && hasLower) ||
(hasUpper && hasNumber) ||
(hasUpper && hasSpecial) ||
(hasLower && hasNumber) ||
(hasLower && hasSpecial) ||
(hasNumber && hasSpecial)
return valid
}

View File

@@ -17,6 +17,9 @@ func RegisterRules(v *validator.Validate) error {
if err := v.RegisterValidation("regexp", NewRegexp().Regexp); err != nil {
return err
}
if err := v.RegisterValidation("password", NewPassword().Password); err != nil {
return err
}
if err := v.RegisterTranslation("exists", *app.Translator,
func(ut ut.Translator) error {
@@ -48,6 +51,16 @@ func RegisterRules(v *validator.Validate) error {
}); err != nil {
return err
}
if err := v.RegisterTranslation("password", *app.Translator,
func(ut ut.Translator) error {
return ut.Add("password", "密码不满足要求8-20位至少包含大小写字母、数字、特殊字符中的两种", true)
},
func(ut ut.Translator, fe validator.FieldError) string {
t, _ := ut.T("password")
return t
}); err != nil {
return err
}
return nil
}

View File

@@ -147,6 +147,10 @@ func (r *Firewall) Port(rule FireInfo, operation Operation) error {
return r.RichRules(rule, operation)
}
// 未设置协议默认为tcp/udp
if rule.Protocol == "" {
rule.Protocol = ProtocolTCPUDP
}
protocols := strings.Split(string(rule.Protocol), "/")
for protocol := range slices.Values(protocols) {
stdout, err := shell.Execf("firewall-cmd --zone=public --%s-port=%d-%d/%s --permanent", operation, rule.PortStart, rule.PortEnd, protocol)