{"record":{"id":"6350432f5b83e974","repo":"flipped-aurora/gin-vue-admin","slug":"s-635043","errorCode":null,"errorMessage":"密码必须包含%s","messagePattern":"密码必须包含(.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"server/utils/password_complexity.go","lineNumber":44,"sourceCode":"\t\tcase unicode.IsPunct(r) || unicode.IsSymbol(r):\n\t\t\thasSpecial = true\n\t\t}\n\t}\n\tvar missing []string\n\tif cfg.PwdRequireUpper && !hasUpper {\n\t\tmissing = append(missing, \"大写字母\")\n\t}\n\tif cfg.PwdRequireLower && !hasLower {\n\t\tmissing = append(missing, \"小写字母\")\n\t}\n\tif cfg.PwdRequireDigit && !hasDigit {\n\t\tmissing = append(missing, \"数字\")\n\t}\n\tif cfg.PwdRequireSpecial && !hasSpecial {\n\t\tmissing = append(missing, \"特殊字符\")\n\t}\n\tif len(missing) > 0 {\n\t\treturn fmt.Errorf(\"密码必须包含%s\", strings.Join(missing, \"、\"))\n\t}\n\treturn nil\n}\n","sourceCodeStart":26,"sourceCodeEnd":48,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/utils/password_complexity.go#L26-L48","documentation":"After checking length, ValidatePasswordComplexity verifies character-class requirements (uppercase, lowercase, digits, special characters). Each enabled requirement in cfg that the password fails is collected and reported as \"密码必须包含%s\" with the missing classes joined by \"、\". It tells the user exactly which character categories to add.","triggerScenarios":"Calling ValidatePasswordComplexity with a password lacking one or more required classes — e.g. cfg.PwdRequireDigit is true but the password has no digits, or PwdRequireSpecial is true but there is no special character.","commonSituations":"Users submit alphabetic-only passwords when policy requires digits/specials; newly enabled complexity flags in security config reject old passwords during reset; multi-byte special characters counted unexpectedly.","solutions":["Add the missing character classes named in the error (uppercase, lowercase, 数字, 特殊字符).","Mirror the enabled requirements (PwdRequireUpper/Lower/Digit/Special) in the frontend validation and hint text.","If policy is too strict for your users, disable the corresponding PwdRequire* flags in the security config."],"exampleFix":"// before\nValidatePasswordComplexity(\"Password\", cfg) // missing digit & special\n\n// after\nValidatePasswordComplexity(\"Password1!\", cfg) // passes all classes","handlingStrategy":"validation","validationCode":"func meetsClasses(pwd string, cfg system.SysSecurityConfig) []string {\n    var missing []string\n    var up, low, dig, sp bool\n    for _, r := range pwd {\n        switch {\n        case unicode.IsUpper(r): up = true\n        case unicode.IsLower(r): low = true\n        case unicode.IsDigit(r): dig = true\n        default: sp = true\n        }\n    }\n    if cfg.PwdRequireUpper && !up { missing = append(missing, \"uppercase\") }\n    if cfg.PwdRequireLower && !low { missing = append(missing, \"lowercase\") }\n    if cfg.PwdRequireDigit && !dig { missing = append(missing, \"digit\") }\n    if cfg.PwdRequireSpecial && !sp { missing = append(missing, \"special\") }\n    return missing\n}","typeGuard":null,"tryCatchPattern":"if err := utils.ValidatePasswordComplexity(pwd, cfg); err != nil {\n    return c.BadRequest(err.Error()) // lists missing classes verbatim\n}","preventionTips":["Mirror PwdRequire* flags in the frontend and display a live checklist","Use a password generator that includes all required classes","Show the policy requirements on the change-password page","Test old passwords against new flags during policy rollout"],"tags":["validation","password","security"],"backgroundTag":"password-complexity-rejected","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}