Auth: Reduce bcrypt cost for faster login on small devices #3718
Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
parent
311288312e
commit
096b306420
2 changed files with 14 additions and 14 deletions
|
@ -10,9 +10,9 @@ import (
|
||||||
"github.com/photoprism/photoprism/pkg/txt"
|
"github.com/photoprism/photoprism/pkg/txt"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
// DefaultPasswordCost specifies the cost of the BCrypt Password Hash,
|
||||||
PasswordCost = 14
|
// see https://github.com/photoprism/photoprism/issues/3718.
|
||||||
)
|
var DefaultPasswordCost = 12
|
||||||
|
|
||||||
// Password represents a password hash.
|
// Password represents a password hash.
|
||||||
type Password struct {
|
type Password struct {
|
||||||
|
@ -64,8 +64,8 @@ func (m *Password) SetPassword(pw string, allowHash bool) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate hash from plain text string.
|
// Generate hash from plain text string using the default password cost.
|
||||||
if bytes, err := bcrypt.GenerateFromPassword([]byte(pw), PasswordCost); err != nil {
|
if bytes, err := bcrypt.GenerateFromPassword([]byte(pw), DefaultPasswordCost); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
m.Hash = string(bytes)
|
m.Hash = string(bytes)
|
||||||
|
@ -125,12 +125,12 @@ func (m *Password) Cost() (int, error) {
|
||||||
return bcrypt.Cost([]byte(m.Hash))
|
return bcrypt.Cost([]byte(m.Hash))
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsEmpty returns true if the password is not set.
|
// IsEmpty returns true if no password is set.
|
||||||
func (m *Password) IsEmpty() bool {
|
func (m *Password) IsEmpty() bool {
|
||||||
return m.Hash == ""
|
return m.Hash == ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns the password hash.
|
// String returns the BCrypt Password Hash.
|
||||||
func (m *Password) String() string {
|
func (m *Password) String() string {
|
||||||
return m.Hash
|
return m.Hash
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,15 +143,15 @@ func TestFindPassword(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPassword_Cost(t *testing.T) {
|
func TestPassword_Cost(t *testing.T) {
|
||||||
t.Run("Default", func(t *testing.T) {
|
t.Run("DefaultPasswordCost", func(t *testing.T) {
|
||||||
p := NewPassword("urrwaxd19ldtz68x", "photoprism", false)
|
p := NewPassword("urrwaxd19ldtz68x", "photoprism", false)
|
||||||
if cost, err := p.Cost(); err != nil {
|
if cost, err := p.Cost(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
} else {
|
} else {
|
||||||
assert.Equal(t, PasswordCost, cost)
|
assert.Equal(t, DefaultPasswordCost, cost)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
t.Run("14", func(t *testing.T) {
|
t.Run("PasswordCost14", func(t *testing.T) {
|
||||||
p := NewPassword("urrwaxd19ldtz68x", "$2a$14$qCcNjxupSJV1gjhgdYxz8e9l0e0fTZosX0s0qhMK54IkI9YOyWLt2", true)
|
p := NewPassword("urrwaxd19ldtz68x", "$2a$14$qCcNjxupSJV1gjhgdYxz8e9l0e0fTZosX0s0qhMK54IkI9YOyWLt2", true)
|
||||||
if cost, err := p.Cost(); err != nil {
|
if cost, err := p.Cost(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -159,7 +159,7 @@ func TestPassword_Cost(t *testing.T) {
|
||||||
assert.Equal(t, 14, cost)
|
assert.Equal(t, 14, cost)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
t.Run("empty password", func(t *testing.T) {
|
t.Run("EmptyPassword", func(t *testing.T) {
|
||||||
p := NewPassword("urrwaxd19ldtz68x", "", false)
|
p := NewPassword("urrwaxd19ldtz68x", "", false)
|
||||||
_, err := p.Cost()
|
_, err := p.Cost()
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
@ -167,18 +167,18 @@ func TestPassword_Cost(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPassword_String(t *testing.T) {
|
func TestPassword_String(t *testing.T) {
|
||||||
t.Run("return string", func(t *testing.T) {
|
t.Run("BCrypt", func(t *testing.T) {
|
||||||
p := NewPassword("urrwaxd19ldtz68x", "lkjhgtyu", false)
|
p := NewPassword("urrwaxd19ldtz68x", "lkjhgtyu", false)
|
||||||
assert.Len(t, p.String(), 60)
|
assert.Len(t, p.String(), 60)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPassword_IsEmpty(t *testing.T) {
|
func TestPassword_IsEmpty(t *testing.T) {
|
||||||
t.Run("false", func(t *testing.T) {
|
t.Run("False", func(t *testing.T) {
|
||||||
p := NewPassword("urrwaxd19ldtz68x", "lkjhgtyu", false)
|
p := NewPassword("urrwaxd19ldtz68x", "lkjhgtyu", false)
|
||||||
assert.False(t, p.IsEmpty())
|
assert.False(t, p.IsEmpty())
|
||||||
})
|
})
|
||||||
t.Run("true", func(t *testing.T) {
|
t.Run("True", func(t *testing.T) {
|
||||||
p := Password{}
|
p := Password{}
|
||||||
assert.True(t, p.IsEmpty())
|
assert.True(t, p.IsEmpty())
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue