[client] Password strength validation

This commit is contained in:
Abhishek Shroff
2025-05-29 00:24:29 +05:30
parent fd32960ab4
commit 486bc4516e
4 changed files with 73 additions and 0 deletions

View File

@@ -12,6 +12,11 @@ storage:
user:
password:
length: 12
lower: 1
upper: 1
numeric: 1
symbols: 1
basedir: /home
perimission: 0

View File

@@ -7,4 +7,9 @@ type Config struct {
}
type PasswordConfig struct {
Length int `koanf:"length"`
Lower int `koanf:"lower"`
Upper int `koanf:"upper"`
Numeric int `koanf:"numeric"`
Symbols int `koanf:"symbols"`
}

View File

@@ -0,0 +1,59 @@
package user
import (
"net/http"
"strconv"
"github.com/shroff/phylum/server/internal/core/errors"
)
type charType int
const (
charTypeOther charType = iota
charTypeLower
charTypeUpper
charTypeNumeric
charTypeSymbol
)
var charTypes = map[rune]charType{}
func init() {
for _, c := range "abcdefghijklmnopqrstuvwxyz" {
charTypes[c] = charTypeLower
}
for _, c := range "ABCDEFGHIJKLMNOPQRSTUVWXYZ" {
charTypes[c] = charTypeUpper
}
for _, c := range "0123456789" {
charTypes[c] = charTypeNumeric
}
for _, c := range "`~!@#$%^&*()-_=+[]{}\\|;:'\",.<>/?" {
charTypes[c] = charTypeSymbol
}
}
func checkPasswordStrength(password string) error {
if len(password) < Cfg.Password.Length {
return errors.NewError(http.StatusBadRequest, "password_invalid", "Must be at least "+strconv.Itoa(Cfg.Password.Length)+" characters long.")
}
count := map[charType]int{}
for _, c := range password {
count[charTypes[c]]++
}
if count[charTypeLower] < Cfg.Password.Lower {
return errors.NewError(http.StatusBadRequest, "password_invalid", "Must have at least "+strconv.Itoa(Cfg.Password.Lower)+" lower case.")
}
if count[charTypeUpper] < Cfg.Password.Upper {
return errors.NewError(http.StatusBadRequest, "password_invalid", "Must have at least "+strconv.Itoa(Cfg.Password.Upper)+" upper case.")
}
if count[charTypeNumeric] < Cfg.Password.Numeric {
return errors.NewError(http.StatusBadRequest, "password_invalid", "Must have at least "+strconv.Itoa(Cfg.Password.Numeric)+" numeric.")
}
if count[charTypeSymbol] < Cfg.Password.Symbols {
return errors.NewError(http.StatusBadRequest, "password_invalid", "Must have at least "+strconv.Itoa(Cfg.Password.Symbols)+" symbols.")
}
return nil
}

View File

@@ -22,6 +22,10 @@ func (m manager) UpdateUserName(user User, name string) error {
}
func (m manager) UpdateUserPassword(user User, password string) error {
if err := checkPasswordStrength(password); err != nil {
return err
}
const q = "UPDATE users SET password_hash = $2::TEXT, modified = NOW() WHERE id = $1::INT"
if hash, err := crypt.Generate(password); err != nil {
return err