46 строки
1.3 KiB
Go
46 строки
1.3 KiB
Go
package webapp
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
// bcryptCost is the work factor for new bcrypt hashes. Matches the
|
|
// "cost 12" assumption from docs/distributed/worker-web-app.md
|
|
// section 5.2; the cost applies to first-run and password-change
|
|
// hashes alike.
|
|
const bcryptCost = 12
|
|
|
|
// HashPassword bcrypts the given plaintext password at the package's
|
|
// configured cost. Returns the encoded hash ready to be persisted.
|
|
func HashPassword(plain string) (string, error) {
|
|
if plain == "" {
|
|
return "", fmt.Errorf("webapp: empty password")
|
|
}
|
|
h, err := bcrypt.GenerateFromPassword([]byte(plain), bcryptCost)
|
|
if err != nil {
|
|
return "", fmt.Errorf("webapp: bcrypt hash: %w", err)
|
|
}
|
|
return string(h), nil
|
|
}
|
|
|
|
// VerifyPassword reports whether the given plaintext matches the
|
|
// given bcrypt hash. A nil error means the password is correct.
|
|
func VerifyPassword(hash, plain string) error {
|
|
return bcrypt.CompareHashAndPassword([]byte(hash), []byte(plain))
|
|
}
|
|
|
|
// MaskToken returns the last 4 characters of a token prefixed with a
|
|
// star mask, e.g. "****abcd". Empty input yields "—". Used on the
|
|
// settings page where the worker's bearer token is shown read-only.
|
|
func MaskToken(token string) string {
|
|
if token == "" {
|
|
return "—"
|
|
}
|
|
if len(token) <= 4 {
|
|
return "****"
|
|
}
|
|
return "****" + token[len(token)-4:]
|
|
}
|