Improve username validation logic.

This commit is contained in:
2025-06-12 15:04:37 +08:00
parent f453ee46a1
commit 41c40fa6d0

View File

@@ -14,6 +14,7 @@ import (
"strings" "strings"
"sync" "sync"
"time" "time"
"unicode"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
) )
@@ -66,13 +67,11 @@ func CreateUser(username, password, cfToken string) (model.UserViewWithToken, er
if !config.AllowRegister() { if !config.AllowRegister() {
return model.UserViewWithToken{}, model.NewRequestError("User registration is not allowed") return model.UserViewWithToken{}, model.NewRequestError("User registration is not allowed")
} }
usernameLen := len([]rune(username))
if usernameLen < 3 || usernameLen > 20 { if err := validateUsername(username); err != nil {
return model.UserViewWithToken{}, model.NewRequestError("Username must be between 3 and 20 characters") return model.UserViewWithToken{}, err
}
if strings.Contains(username, " ") {
return model.UserViewWithToken{}, model.NewRequestError("Username cannot contain spaces")
} }
if len(password) < 6 || len(password) > 20 { if len(password) < 6 || len(password) > 20 {
return model.UserViewWithToken{}, model.NewRequestError("Password must be between 6 and 20 characters") return model.UserViewWithToken{}, model.NewRequestError("Password must be between 6 and 20 characters")
} }
@@ -331,12 +330,8 @@ func GetUserByUsername(username string) (model.UserView, error) {
} }
func ChangeUsername(uid uint, newUsername string) (model.UserView, error) { func ChangeUsername(uid uint, newUsername string) (model.UserView, error) {
usernameLen := len([]rune(newUsername)) if err := validateUsername(newUsername); err != nil {
if usernameLen < 3 || usernameLen > 20 { return model.UserView{}, err
return model.UserView{}, model.NewRequestError("Username must be between 3 and 20 characters")
}
if strings.Contains(newUsername, " ") {
return model.UserView{}, model.NewRequestError("Username cannot contain spaces")
} }
user, err := dao.GetUserByID(uid) user, err := dao.GetUserByID(uid)
@@ -376,3 +371,25 @@ func GetMe(uid uint) (model.UserViewWithToken, error) {
} }
return user.ToView().WithToken(token), nil return user.ToView().WithToken(token), nil
} }
func validateUsername(username string) error {
usernameLen := len([]rune(username))
if usernameLen < 3 || usernameLen > 20 {
return model.NewRequestError("Username must be between 3 and 20 characters")
}
if strings.Contains(username, " ") {
return model.NewRequestError("Username cannot contain spaces")
}
for _, r := range []rune(username) {
if r == ' ' || r == '\n' || r == '\r' || r == '\t' || r == '\v' || r == '\f' {
return model.NewRequestError("Username cannot contain whitespace characters")
}
if (r >= 0 && r <= 31) || r == 127 {
return model.NewRequestError("Username cannot contain control characters")
}
if unicode.IsControl(r) || unicode.Is(unicode.C, r) {
return model.NewRequestError("Username cannot contain invisible Unicode control characters")
}
}
return nil
}