94 lines
2.4 KiB
Go
94 lines
2.4 KiB
Go
package utils
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"math/rand"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
var (
|
|
usernamePattern = regexp.MustCompile(`^[0-9A-Za-z]+$`)
|
|
passwordPattern = regexp.MustCompile(`^[!-~]+$`)
|
|
)
|
|
|
|
// IsValidUsername reports whether s is a valid username.
|
|
func IsValidUsername(s string) bool {
|
|
return usernamePattern.MatchString(s)
|
|
}
|
|
|
|
// IsValidPassword reports whether s is a valid password.
|
|
func IsValidPassword(s string) bool {
|
|
return passwordPattern.MatchString(s)
|
|
}
|
|
|
|
// ComputePasswordHash returns the lowercased SHA-256 hex digest of password.
|
|
func ComputePasswordHash(password string) string {
|
|
sum := sha256.Sum256([]byte(password))
|
|
return hex.EncodeToString(sum[:])
|
|
}
|
|
|
|
// GenerateUUID returns a new UUID string, preferring version 1 (mirroring
|
|
// python's uuid.uuid1()), falling back to a random version-4 UUID on error.
|
|
func GenerateUUID() string {
|
|
u, err := uuid.NewUUID()
|
|
if err != nil {
|
|
u = uuid.New()
|
|
}
|
|
return u.String()
|
|
}
|
|
|
|
// GenerateToken returns a SHA-256 hex digest of the username concatenated with
|
|
// a fresh UUID.
|
|
func GenerateToken(username string) string {
|
|
sum := sha256.Sum256([]byte(username + GenerateUUID()))
|
|
return hex.EncodeToString(sum[:])
|
|
}
|
|
|
|
// GenerateSalt returns a random salt in the inclusive range [0, 6172748).
|
|
func GenerateSalt() int {
|
|
return rand.Intn(6172748)
|
|
}
|
|
|
|
// ComputePasswordHashWithSalt returns the lowercased SHA-256 hex digest of
|
|
// passwordHashed concatenated with the decimal string form of salt.
|
|
func ComputePasswordHashWithSalt(passwordHashed string, salt int) string {
|
|
sum := sha256.Sum256([]byte(passwordHashed + strconv.Itoa(salt)))
|
|
return hex.EncodeToString(sum[:])
|
|
}
|
|
|
|
// GetCurrentTimestamp returns the current UNIX timestamp in seconds.
|
|
func GetCurrentTimestamp() int {
|
|
return int(time.Now().Unix())
|
|
}
|
|
|
|
// GetTokenExpireOn returns the timestamp 2 days from now, used as the token
|
|
// expiry.
|
|
func GetTokenExpireOn() int {
|
|
return GetCurrentTimestamp() + 60*60*24*2
|
|
}
|
|
|
|
// Str2Bool reports whether s, compared case-insensitively, equals "true".
|
|
func Str2Bool(s string) bool {
|
|
return strings.ToLower(s) == "true"
|
|
}
|
|
|
|
// GCD returns the greatest common divisor of a and b via the Euclidean
|
|
// algorithm.
|
|
func GCD(a, b int) int {
|
|
for b != 0 {
|
|
a, b = b, a%b
|
|
}
|
|
return a
|
|
}
|
|
|
|
// LCM returns the least common multiple of a and b.
|
|
func LCM(a, b int) int {
|
|
return (a * b) / GCD(a, b)
|
|
}
|