mirror of
https://github.com/volatiletech/authboss.git
synced 2025-09-16 09:06:20 +02:00
Add better validation error support
- Add map function for ErrorList - Creat new events for recover
This commit is contained in:
@@ -7,6 +7,8 @@ type Event int
|
|||||||
const (
|
const (
|
||||||
EventRegister Event = iota
|
EventRegister Event = iota
|
||||||
EventAuth
|
EventAuth
|
||||||
|
EventRecoverStart
|
||||||
|
EventRecoverEnd
|
||||||
)
|
)
|
||||||
|
|
||||||
// Before callbacks can interrupt the flow by returning an error. This is used to stop
|
// Before callbacks can interrupt the flow by returning an error. This is used to stop
|
||||||
|
@@ -31,6 +31,7 @@ func (r Rules) Errors(toValidate string) authboss.ErrorList {
|
|||||||
ln := len(toValidate)
|
ln := len(toValidate)
|
||||||
if ln == 0 {
|
if ln == 0 {
|
||||||
errs = append(errs, authboss.FieldError{r.Field, errors.New("Cannot be blank")})
|
errs = append(errs, authboss.FieldError{r.Field, errors.New("Cannot be blank")})
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.MustMatch != nil {
|
if r.MustMatch != nil {
|
||||||
|
@@ -22,6 +22,8 @@ func (v *Validate) Initialize(config *authboss.Config) error {
|
|||||||
v.Password = config.ValidatePassword
|
v.Password = config.ValidatePassword
|
||||||
|
|
||||||
config.Callbacks.Before(authboss.EventRegister, v.BeforeRegister)
|
config.Callbacks.Before(authboss.EventRegister, v.BeforeRegister)
|
||||||
|
config.Callbacks.Before(authboss.EventRecoverStart, v.BeforeRegister)
|
||||||
|
config.Callbacks.Before(authboss.EventRecoverEnd, v.BeforeRegister)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -7,17 +7,6 @@ import (
|
|||||||
|
|
||||||
type ErrorList []error
|
type ErrorList []error
|
||||||
|
|
||||||
// FieldError represents an error that occurs during validation and is always
|
|
||||||
// attached to field on a form.
|
|
||||||
type FieldError struct {
|
|
||||||
Name string
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f FieldError) Error() string {
|
|
||||||
return fmt.Sprintf("%s: %v", f.Name, f.Err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error satisfies the error interface.
|
// Error satisfies the error interface.
|
||||||
func (e ErrorList) Error() string {
|
func (e ErrorList) Error() string {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
@@ -33,6 +22,33 @@ func (e ErrorList) Error() string {
|
|||||||
return b.String()
|
return b.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Map groups errors by their field name
|
||||||
|
func (e ErrorList) Map() map[string][]string {
|
||||||
|
m := make(map[string][]string)
|
||||||
|
|
||||||
|
for _, err := range e {
|
||||||
|
fieldErr, ok := err.(FieldError)
|
||||||
|
if !ok {
|
||||||
|
m[""] = append(m[""], err.Error())
|
||||||
|
} else {
|
||||||
|
m[fieldErr.Name] = append(m[fieldErr.Name], fieldErr.Err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
// FieldError represents an error that occurs during validation and is always
|
||||||
|
// attached to field on a form.
|
||||||
|
type FieldError struct {
|
||||||
|
Name string
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f FieldError) Error() string {
|
||||||
|
return fmt.Sprintf("%s: %v", f.Name, f.Err)
|
||||||
|
}
|
||||||
|
|
||||||
// Validator is anything that can validate a string and provide a list of errors
|
// Validator is anything that can validate a string and provide a list of errors
|
||||||
// and describe its set of rules.
|
// and describe its set of rules.
|
||||||
type Validator interface {
|
type Validator interface {
|
||||||
|
@@ -6,8 +6,57 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestErrorList_Error(t *testing.T) {
|
func TestErrorList_Error(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
errList := ErrorList{errors.New("one"), errors.New("two")}
|
errList := ErrorList{errors.New("one"), errors.New("two")}
|
||||||
if e := errList.Error(); e != "one, two" {
|
if e := errList.Error(); e != "one, two" {
|
||||||
t.Error("Wrong value for error:", e)
|
t.Error("Wrong value for error:", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestErrorList_Map(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
errNotLong := "not long enough"
|
||||||
|
errEmail := "should be an email"
|
||||||
|
errAsploded := "asploded"
|
||||||
|
|
||||||
|
errList := ErrorList{
|
||||||
|
FieldError{"username", errors.New(errNotLong)},
|
||||||
|
FieldError{"username", errors.New(errEmail)},
|
||||||
|
FieldError{"password", errors.New(errNotLong)},
|
||||||
|
errors.New(errAsploded),
|
||||||
|
}
|
||||||
|
|
||||||
|
m := errList.Map()
|
||||||
|
if len(m) != 3 {
|
||||||
|
t.Error("Wrong number of fields:", len(m))
|
||||||
|
}
|
||||||
|
|
||||||
|
usernameErrs := m["username"]
|
||||||
|
if len(usernameErrs) != 2 {
|
||||||
|
t.Error("Wrong number of username errors:", len(usernameErrs))
|
||||||
|
}
|
||||||
|
if usernameErrs[0] != errNotLong {
|
||||||
|
t.Error("Wrong username error at 0:", usernameErrs[0])
|
||||||
|
}
|
||||||
|
if usernameErrs[1] != errEmail {
|
||||||
|
t.Error("Wrong username error at 1:", usernameErrs[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
passwordErrs := m["password"]
|
||||||
|
if len(passwordErrs) != 1 {
|
||||||
|
t.Error("Wrong number of password errors:", len(passwordErrs))
|
||||||
|
}
|
||||||
|
if passwordErrs[0] != errNotLong {
|
||||||
|
t.Error("Wrong password error at 0:", passwordErrs[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
unknownErrs := m[""]
|
||||||
|
if len(unknownErrs) != 1 {
|
||||||
|
t.Error("Wrong number of unkown errors:", len(unknownErrs))
|
||||||
|
}
|
||||||
|
if unknownErrs[0] != errAsploded {
|
||||||
|
t.Error("Wrong unkown error at 0:", unknownErrs[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user