1
0
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:
Aaron 2015-02-24 11:13:46 -08:00
parent c723f46a3e
commit faa35b66be
2 changed files with 60 additions and 12 deletions

View File

@ -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
}

View File

@ -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)