CLI: Improve length check in "photoprism passwd" command #3482

Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
Michael Mayer 2023-06-19 17:24:02 +02:00
parent 054a0764c5
commit 87b6d72477
6 changed files with 26 additions and 19 deletions

View file

@ -15,6 +15,7 @@ import (
"github.com/photoprism/photoprism/internal/entity"
"github.com/photoprism/photoprism/pkg/clean"
"github.com/photoprism/photoprism/pkg/rnd"
"github.com/photoprism/photoprism/pkg/txt"
)
// PasswdCommand configures the command name, flags, and action.
@ -67,12 +68,14 @@ func passwdAction(ctx *cli.Context) error {
return fmt.Errorf("user %s has been deleted", clean.LogQuote(id))
}
log.Infof("please enter a new password for %s (minimum %d characters)\n", clean.Log(m.Username()), entity.PasswordLength)
log.Infof("please enter a new password for %s (%d-%d characters)\n", clean.Log(m.Username()), entity.PasswordLength, txt.ClipPassword)
newPassword := getPassword("New Password: ")
if len(newPassword) < 6 {
return errors.New("new password is too short, please try again")
if len([]rune(newPassword)) < entity.PasswordLength {
return fmt.Errorf("password must have at least %d characters", entity.PasswordLength)
} else if len(newPassword) > txt.ClipPassword {
return fmt.Errorf("password must have less than %d characters", txt.ClipPassword)
}
retypePassword := getPassword("Retype Password: ")

View file

@ -11,6 +11,7 @@ import (
"github.com/photoprism/photoprism/internal/entity"
"github.com/photoprism/photoprism/internal/form"
"github.com/photoprism/photoprism/pkg/clean"
"github.com/photoprism/photoprism/pkg/txt"
)
// UsersAddCommand configures the command name, flags, and action.
@ -90,10 +91,12 @@ func usersAddAction(ctx *cli.Context) error {
frm.UserEmail = clean.Email(res)
}
if interactive && len(ctx.String("password")) < entity.PasswordLength {
if interactive && len([]rune(ctx.String("password"))) < entity.PasswordLength {
validate := func(input string) error {
if len(input) < entity.PasswordLength {
if len([]rune(input)) < entity.PasswordLength {
return fmt.Errorf("password must have at least %d characters", entity.PasswordLength)
} else if len(input) > txt.ClipPassword {
return fmt.Errorf("password must have less than %d characters", txt.ClipPassword)
}
return nil
}

View file

@ -31,7 +31,7 @@ const (
// UsernameLength specifies the minimum length of the username in characters.
var UsernameLength = 1
// PasswordLength specifies the minimum length of the password in characters.
// PasswordLength specifies the minimum length of a password in characters (runes, not bytes).
var PasswordLength = 4
// UsersPath is the relative path for user assets.
@ -768,8 +768,10 @@ func (m *User) SetPassword(password string) error {
return fmt.Errorf("only registered users can change their password")
}
if len(password) < PasswordLength {
if len([]rune(password)) < PasswordLength {
return fmt.Errorf("password must have at least %d characters", PasswordLength)
} else if len(password) > txt.ClipPassword {
return fmt.Errorf("password must have less than %d characters", txt.ClipPassword)
}
pw := NewPassword(m.UserUID, password, false)

View file

@ -7,14 +7,17 @@ import (
"github.com/photoprism/photoprism/internal/form"
"github.com/photoprism/photoprism/pkg/clean"
"github.com/photoprism/photoprism/pkg/txt"
)
// AddUser creates a new user record and sets the password in a single transaction.
func AddUser(frm form.User) error {
user := NewUser().SetFormValues(frm)
if len(frm.Password) < PasswordLength {
if len([]rune(frm.Password)) < PasswordLength {
return fmt.Errorf("password must have at least %d characters", PasswordLength)
} else if len(frm.Password) > txt.ClipPassword {
return fmt.Errorf("password must have less than %d characters", txt.ClipPassword)
}
if err := user.Validate(); err != nil {

View file

@ -46,12 +46,14 @@ func NewPassword(uid, pw string, allowHash bool) Password {
// SetPassword sets a new password stored as hash.
func (m *Password) SetPassword(pw string, allowHash bool) error {
// Remove leading and trailing white space.
pw = clean.Password(pw)
if l := len(pw); l > txt.ClipPassword {
return fmt.Errorf("password is too long")
} else if l < 1 {
// Check if password is too short or too long.
if len([]rune(pw)) < 1 {
return fmt.Errorf("password is too short")
} else if len(pw) > txt.ClipPassword {
return fmt.Errorf("password must have less than %d characters", txt.ClipPassword)
}
// Check if string already is a bcrypt hash.

View file

@ -109,13 +109,7 @@ func Attr(s string) string {
return list.ParseAttr(s).String()
}
// Password returns the sanitized password string with trimmed whitespace.
// Password returns the password string with all leading and trailing white space removed.
func Password(s string) string {
s = strings.TrimSpace(s)
if s == "" || reject(s, txt.ClipPassword) {
return ""
}
return s
return strings.TrimSpace(s)
}