Closes: https://todo.sr.ht/~emersion/soju/136
---
Addresses feedback on patch.
- returning bool for if the password is upgraded
- camelCase no longer applicable to highlighted point
- using the SetPassword function instead of duplicating logic
database/database.go | 24 +++++++++++++++++++-----
downstream.go | 10 +++++++++-
2 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/database/database.go b/database/database.go
index 977d1b7..1c22bfb 100644
--- a/database/database.go
+++ b/database/database.go
@@ -71,18 +71,32 @@ type User struct {
Admin bool
}
-func (u *User) CheckPassword(password string) error {
+func (u *User) CheckPassword(password string) (upgraded bool, err error) {
// Password auth disabled
if u.Password == "" {
- return fmt.Errorf("password auth disabled")
+ return false, fmt.Errorf("password auth disabled")
}
- err := bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
+ err = bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
if err != nil {
- return fmt.Errorf("wrong password: %v", err)
+ return false, fmt.Errorf("wrong password: %v", err)
}
- return nil
+ passCost, err := bcrypt.Cost([]byte(u.Password))
+ if err != nil {
+ return false, fmt.Errorf("invalid password cost: %v", err)
+ }
+
+ if passCost >= bcrypt.DefaultCost {
+ return false, nil
+ }
+
+ err = u.SetPassword(password)
+ if err != nil {
+ return false, err
+ }
+
+ return true, nil
}
func (u *User) SetPassword(password string) error {
diff --git a/downstream.go b/downstream.go
index 8fdbceb..0d46bf0 100644
--- a/downstream.go
+++ b/downstream.go
@@ -1311,10 +1311,18 @@ func (dc *downstreamConn) authenticate(ctx context.Context, username, password s
return newInvalidUsernameOrPasswordError(fmt.Errorf("user not found: %w", err))
}
- if err := u.CheckPassword(password); err != nil {
+ upgraded, err := u.CheckPassword(password)
+ if err != nil {
return newInvalidUsernameOrPasswordError(err)
}
+ if upgraded {
+ err := dc.srv.db.StoreUser(ctx, u)
+ if err != nil {
+ return err
+ }
+ }
+
dc.user = dc.srv.getUser(username)
if dc.user == nil {
return fmt.Errorf("user exists in the DB but hasn't been loaded by the bouncer -- a restart may help")
--
2.37.0