Allow underscores in usernames (#703)

* Allow underscores in usernames

# Summary
Some organizations use underscores in github usernames.
Filtering those out prevents a smooth user creation process.
This PR adds underscores to the "alphanumeric characters and dash" filter.

# Test Plan
Tested it in an organization with underscores in the usernames: it works.

* Add missing en-US locale for alphanumeric-dashes-underscores validation

---------

Co-authored-by: Thomas Miceli <tho.miceli@gmail.com>
This commit is contained in:
Marton Neher
2026-06-25 11:03:15 -07:00
committed by GitHub
parent 4a83e3ecda
commit d70953c75c
3 changed files with 14 additions and 1 deletions
+1 -1
View File
@@ -284,7 +284,7 @@ type UserDTO struct {
}
type OAuthRegisterDTO struct {
Username string `form:"username" validate:"required,max=24,alphanumdash,notreserved"`
Username string `form:"username" validate:"required,max=24,alphanumdashunder,notreserved"`
Email string `form:"email" validate:"omitempty,email"`
}
+1
View File
@@ -396,6 +396,7 @@ validation.should-not-be-empty: Field %s should not be empty
validation.should-not-include-sub-directory: Field %s should not include a sub directory
validation.should-only-contain-alphanumeric-characters: Field %s should only contain alphanumeric characters
validation.should-only-contain-alphanumeric-characters-and-dashes: Field %s should only contain alphanumeric characters and dashes
validation.should-only-contain-alphanumeric-characters-and-dashes-and-underscores: Field %s should only contain alphanumeric characters, dashes and underscores
validation.not-enough: Not enough %s
validation.invalid: Invalid %s
validation.invalid-gist-topics: Invalid gist topics, they must start with a letter or number, consist of 50 characters or less, and can include hyphens
+12
View File
@@ -19,6 +19,8 @@ func NewValidator() *OpengistValidator {
_ = v.RegisterValidation("notreserved", validateReservedKeywords)
_ = v.RegisterValidation("alphanumdash", validateAlphaNumDash)
_ = v.RegisterValidation("alphanumdashorempty", validateAlphaNumDashOrEmpty)
_ = v.RegisterValidation("alphanumdashunder", validateAlphaNumDashUnder)
_ = v.RegisterValidation("alphanumdashunderorempty", validateAlphaNumDashUnderOrEmpty)
_ = v.RegisterValidation("gisttopics", validateGistTopics)
_ = v.RegisterValidation("expirationdate", validateExpirationDate)
return &OpengistValidator{v}
@@ -47,6 +49,8 @@ func ValidationMessages(err *error, locale *i18n.Locale) string {
messages[i] = locale.String("validation.should-only-contain-alphanumeric-characters", e.Field())
case "alphanumdash", "alphanumdashorempty":
messages[i] = locale.String("validation.should-only-contain-alphanumeric-characters-and-dashes", e.Field())
case "alphanumdashunder", "alphanumdashunderorempty":
messages[i] = locale.String("validation.should-only-contain-alphanumeric-characters-and-dashes-and-underscores", e.Field())
case "min":
messages[i] = locale.String("validation.not-enough", e.Field())
case "notreserved":
@@ -82,6 +86,14 @@ func validateAlphaNumDashOrEmpty(fl validator.FieldLevel) bool {
return regexp.MustCompile(`^$|^[a-zA-Z0-9-]+$`).MatchString(fl.Field().String())
}
func validateAlphaNumDashUnder(fl validator.FieldLevel) bool {
return regexp.MustCompile(`^[a-zA-Z0-9-_]+$`).MatchString(fl.Field().String())
}
func validateAlphaNumDashUnderOrEmpty(fl validator.FieldLevel) bool {
return regexp.MustCompile(`^$|^[a-zA-Z0-9-_]+$`).MatchString(fl.Field().String())
}
func validateGistTopics(fl validator.FieldLevel) bool {
topicsInput := fl.Field().String()
if topicsInput == "" {