mirror of
https://github.com/volatiletech/authboss.git
synced 2025-02-09 13:47:09 +02:00
Add additional rule options.
This commit is contained in:
parent
c723f46a3e
commit
faa35b66be
41
rules.go
41
rules.go
@ -19,6 +19,7 @@ type Rules struct {
|
||||
MustMatch *regexp.Regexp
|
||||
MinLength, MaxLength int
|
||||
MinLetters int
|
||||
MinLower, MinUpper int
|
||||
MinNumeric int
|
||||
MinSymbols int
|
||||
AllowWhitespace bool
|
||||
@ -49,10 +50,16 @@ func (r Rules) Errors(toValidate string) ErrorList {
|
||||
errs = append(errs, FieldError{r.FieldName, errors.New(r.lengthErr())})
|
||||
}
|
||||
|
||||
chars, numeric, symbols, whitespace := tallyCharacters(toValidate)
|
||||
if chars < r.MinLetters {
|
||||
upper, lower, numeric, symbols, whitespace := tallyCharacters(toValidate)
|
||||
if upper+lower < r.MinLetters {
|
||||
errs = append(errs, FieldError{r.FieldName, errors.New(r.charErr())})
|
||||
}
|
||||
if upper < r.MinUpper {
|
||||
errs = append(errs, FieldError{r.FieldName, errors.New(r.upperErr())})
|
||||
}
|
||||
if upper < r.MinLower {
|
||||
errs = append(errs, FieldError{r.FieldName, errors.New(r.lowerErr())})
|
||||
}
|
||||
if numeric < r.MinNumeric {
|
||||
errs = append(errs, FieldError{r.FieldName, errors.New(r.numericErr())})
|
||||
}
|
||||
@ -89,6 +96,12 @@ func (r Rules) Rules() []string {
|
||||
if e := r.charErr(); len(e) > 0 {
|
||||
rules = append(rules, e)
|
||||
}
|
||||
if e := r.upperErr(); len(e) > 0 {
|
||||
rules = append(rules, e)
|
||||
}
|
||||
if e := r.lowerErr(); len(e) > 0 {
|
||||
rules = append(rules, e)
|
||||
}
|
||||
if e := r.numericErr(); len(e) > 0 {
|
||||
rules = append(rules, e)
|
||||
}
|
||||
@ -119,6 +132,20 @@ func (r Rules) charErr() (err string) {
|
||||
return err
|
||||
}
|
||||
|
||||
func (r Rules) upperErr() (err string) {
|
||||
if r.MinUpper > 0 {
|
||||
err = fmt.Sprintf("Must contain at least %d uppercase letters", r.MinUpper)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (r Rules) lowerErr() (err string) {
|
||||
if r.MinLower > 0 {
|
||||
err = fmt.Sprintf("Must contain at least %d lowercase letters", r.MinLower)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (r Rules) numericErr() (err string) {
|
||||
if r.MinNumeric > 0 {
|
||||
err = fmt.Sprintf("Must contain at least %d numbers", r.MinNumeric)
|
||||
@ -133,11 +160,15 @@ func (r Rules) symbolErr() (err string) {
|
||||
return err
|
||||
}
|
||||
|
||||
func tallyCharacters(s string) (chars, numeric, symbols, whitespace int) {
|
||||
func tallyCharacters(s string) (upper, lower, numeric, symbols, whitespace int) {
|
||||
for _, c := range s {
|
||||
switch {
|
||||
case unicode.IsLetter(c):
|
||||
chars++
|
||||
if unicode.IsUpper(c) {
|
||||
upper++
|
||||
} else {
|
||||
lower++
|
||||
}
|
||||
case unicode.IsDigit(c):
|
||||
numeric++
|
||||
case unicode.IsSpace(c):
|
||||
@ -147,5 +178,5 @@ func tallyCharacters(s string) (chars, numeric, symbols, whitespace int) {
|
||||
}
|
||||
}
|
||||
|
||||
return chars, numeric, symbols, whitespace
|
||||
return upper, lower, numeric, symbols, whitespace
|
||||
}
|
||||
|
@ -48,6 +48,16 @@ func TestRules_Errors(t *testing.T) {
|
||||
"13345",
|
||||
"email: Must contain at least 5 letters",
|
||||
},
|
||||
{
|
||||
Rules{FieldName: "email", MinUpper: 5},
|
||||
"hi",
|
||||
"email: Must contain at least 5 uppercase letters",
|
||||
},
|
||||
{
|
||||
Rules{FieldName: "email", MinLower: 5},
|
||||
"hi",
|
||||
"email: Must contain at least 5 lowercase letters",
|
||||
},
|
||||
{
|
||||
Rules{FieldName: "email", MinSymbols: 5},
|
||||
"hi",
|
||||
@ -90,8 +100,10 @@ func TestRules_Rules(t *testing.T) {
|
||||
MinLength: 1,
|
||||
MaxLength: 2,
|
||||
MinLetters: 3,
|
||||
MinNumeric: 4,
|
||||
MinSymbols: 5,
|
||||
MinUpper: 4,
|
||||
MinLower: 5,
|
||||
MinNumeric: 6,
|
||||
MinSymbols: 7,
|
||||
AllowWhitespace: false,
|
||||
}
|
||||
|
||||
@ -101,8 +113,10 @@ func TestRules_Rules(t *testing.T) {
|
||||
"Must adhere to this regexp",
|
||||
"Must be between 1 and 2 characters",
|
||||
"Must contain at least 3 letters",
|
||||
"Must contain at least 4 numbers",
|
||||
"Must contain at least 5 symbols",
|
||||
"Must contain at least 4 uppercase letters",
|
||||
"Must contain at least 5 lowercase letters",
|
||||
"Must contain at least 6 numbers",
|
||||
"Must contain at least 7 symbols",
|
||||
}
|
||||
|
||||
for i, toFind := range mustFind {
|
||||
@ -128,9 +142,12 @@ func TestRules_IsValid(t *testing.T) {
|
||||
func TestTallyCharacters(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
c, n, s, w := tallyCharacters("123abcDEF@#$%^* ")
|
||||
if c != 6 {
|
||||
t.Error("Number of chars:", c)
|
||||
u, l, n, s, w := tallyCharacters("123abcDEF@#$%^* ")
|
||||
if u != 3 {
|
||||
t.Error("Number of upper:", u)
|
||||
}
|
||||
if l != 3 {
|
||||
t.Error("Number of lower:", l)
|
||||
}
|
||||
if n != 3 {
|
||||
t.Error("Number of numerics:", n)
|
||||
|
Loading…
x
Reference in New Issue
Block a user