mirror of
https://github.com/miniflux/v2.git
synced 2025-06-27 16:36:00 +00:00
feat: validate usernames upon creation
The validation doesn't apply to already created usernames. This should close #925
This commit is contained in:
parent
518bc4d6ff
commit
e22520fc55
2 changed files with 49 additions and 1 deletions
|
@ -6,6 +6,7 @@ package validator // import "miniflux.app/v2/internal/validator"
|
||||||
import (
|
import (
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
"miniflux.app/v2/internal/locale"
|
"miniflux.app/v2/internal/locale"
|
||||||
"miniflux.app/v2/internal/model"
|
"miniflux.app/v2/internal/model"
|
||||||
|
@ -22,6 +23,10 @@ func ValidateUserCreationWithPassword(store *storage.Storage, request *model.Use
|
||||||
return locale.NewLocalizedError("error.user_already_exists")
|
return locale.NewLocalizedError("error.user_already_exists")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := validateUsername(request.Username); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err := validatePassword(request.Password); err != nil {
|
if err := validatePassword(request.Password); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -146,6 +151,23 @@ func validatePassword(password string) *locale.LocalizedError {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// validateUsername return an error if the `username` argument contains
|
||||||
|
// a character that isn't alphanumerical nor `_` and `-`.
|
||||||
|
func validateUsername(username string) *locale.LocalizedError {
|
||||||
|
if strings.ContainsFunc(username, func(r rune) bool {
|
||||||
|
if unicode.IsLetter(r) || unicode.IsNumber(r) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if r == '_' || r == '-' || r == '@' || r == '.' {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}) {
|
||||||
|
return locale.NewLocalizedError("error.invalid_username")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func validateTheme(theme string) *locale.LocalizedError {
|
func validateTheme(theme string) *locale.LocalizedError {
|
||||||
themes := model.Themes()
|
themes := model.Themes()
|
||||||
if _, found := themes[theme]; !found {
|
if _, found := themes[theme]; !found {
|
||||||
|
|
|
@ -3,7 +3,11 @@
|
||||||
|
|
||||||
package validator // import "miniflux.app/v2/internal/validator"
|
package validator // import "miniflux.app/v2/internal/validator"
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"miniflux.app/v2/internal/locale"
|
||||||
|
)
|
||||||
|
|
||||||
func TestIsValidURL(t *testing.T) {
|
func TestIsValidURL(t *testing.T) {
|
||||||
scenarios := map[string]bool{
|
scenarios := map[string]bool{
|
||||||
|
@ -77,3 +81,25 @@ func TestIsValidDomain(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestValidateUsername(t *testing.T) {
|
||||||
|
scenarios := map[string]*locale.LocalizedError{
|
||||||
|
"jvoisin": nil,
|
||||||
|
"j.voisin": nil,
|
||||||
|
"j@vois.in": nil,
|
||||||
|
"invalid username": locale.NewLocalizedError("error.invalid_username"),
|
||||||
|
}
|
||||||
|
|
||||||
|
for username, expected := range scenarios {
|
||||||
|
result := validateUsername(username)
|
||||||
|
if expected == nil {
|
||||||
|
if result != nil {
|
||||||
|
t.Errorf(`got an unexpected error for %q instead of nil: %v`, username, result)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if result == nil {
|
||||||
|
t.Errorf(`expected an error, got nil.`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue