mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-02 13:30:13 +00:00
67 lines
1.5 KiB
Go
67 lines
1.5 KiB
Go
package auth
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
const (
|
|
// BcryptCost is the cost factor for bcrypt hashing
|
|
// Higher values are more secure but slower
|
|
BcryptCost = 12
|
|
|
|
// MinPasswordLength is the minimum required password length
|
|
MinPasswordLength = 12
|
|
)
|
|
|
|
// HashPassword generates a bcrypt hash from a plain text password
|
|
func HashPassword(password string) (string, error) {
|
|
bytes, err := bcrypt.GenerateFromPassword([]byte(password), hashPasswordCost())
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return string(bytes), nil
|
|
}
|
|
|
|
// CheckPasswordHash compares a plain text password with a hash
|
|
func CheckPasswordHash(password, hash string) bool {
|
|
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
|
|
return err == nil
|
|
}
|
|
|
|
// ValidatePasswordComplexity checks if a password meets complexity requirements
|
|
func ValidatePasswordComplexity(password string) error {
|
|
if len(password) < MinPasswordLength {
|
|
return fmt.Errorf("password must be at least %d characters long", MinPasswordLength)
|
|
}
|
|
|
|
// Let users choose their own passwords beyond length.
|
|
// No character type requirements.
|
|
return nil
|
|
}
|
|
|
|
func hashPasswordCost() int {
|
|
if !runningUnderGoTest() {
|
|
return BcryptCost
|
|
}
|
|
|
|
raw := strings.TrimSpace(os.Getenv("PULSE_TEST_BCRYPT_COST"))
|
|
if raw == "" {
|
|
return BcryptCost
|
|
}
|
|
|
|
cost, err := strconv.Atoi(raw)
|
|
if err != nil || cost < bcrypt.MinCost || cost > bcrypt.MaxCost {
|
|
return BcryptCost
|
|
}
|
|
|
|
return cost
|
|
}
|
|
|
|
func runningUnderGoTest() bool {
|
|
return strings.HasSuffix(os.Args[0], ".test")
|
|
}
|