fix(cabana): enforce the 4-character password minimum on the Administrators form
The form's min:4 rule never applied: the model validator skips string min and max. storePassword now refuses a typed password under 4 characters with a 422 on the field, next to the 72-byte check (D-11). Found by TestAdministratorsPasswordAndIdentity.
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
"git.golem15.com/golem15/summercms/modules/backpack"
|
"git.golem15.com/golem15/summercms/modules/backpack"
|
||||||
"git.golem15.com/golem15/summercms/modules/bouncer"
|
"git.golem15.com/golem15/summercms/modules/bouncer"
|
||||||
@@ -841,13 +842,24 @@ func submittedPassword(ctx context.Context) string {
|
|||||||
return plain
|
return plain
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// adminPasswordMinChars is the shortest password the Administrators form
|
||||||
|
// accepts, in characters (D-11).
|
||||||
|
const adminPasswordMinChars = 4
|
||||||
|
|
||||||
// storePassword hashes a typed password onto user and reports whether one
|
// storePassword hashes a typed password onto user and reports whether one
|
||||||
// was typed. A password over bcrypt's 72-byte limit is a 422 on the field.
|
// was typed. A password under adminPasswordMinChars characters or over
|
||||||
|
// bcrypt's 72-byte limit is a 422 on the field. The length is checked here
|
||||||
|
// because the form's min:4 rule is a string rule, which the model validator
|
||||||
|
// does not apply.
|
||||||
func (c usersAdmin) storePassword(ctx context.Context, user *BackendUser) (bool, error) {
|
func (c usersAdmin) storePassword(ctx context.Context, user *BackendUser) (bool, error) {
|
||||||
plain := submittedPassword(ctx)
|
plain := submittedPassword(ctx)
|
||||||
if plain == "" {
|
if plain == "" {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
if utf8.RuneCountInString(plain) < adminPasswordMinChars {
|
||||||
|
message := accountMessage(ctx, c.translator(), "min.string", "password", map[string]string{"min": strconv.Itoa(adminPasswordMinChars)})
|
||||||
|
return false, &ValidationError{Details: map[string]any{"password": []string{message}}}
|
||||||
|
}
|
||||||
if len(plain) > passwordMaxBytes {
|
if len(plain) > passwordMaxBytes {
|
||||||
message := accountMessage(ctx, c.translator(), "max.string", "password", map[string]string{"max": strconv.Itoa(passwordMaxBytes)})
|
message := accountMessage(ctx, c.translator(), "max.string", "password", map[string]string{"max": strconv.Itoa(passwordMaxBytes)})
|
||||||
return false, &ValidationError{Details: map[string]any{"password": []string{message}}}
|
return false, &ValidationError{Details: map[string]any{"password": []string{message}}}
|
||||||
|
|||||||
Reference in New Issue
Block a user