using bcrypt
parent
7b934e00a6
commit
876ac33d1b
|
|
@ -1,27 +1,36 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
ID int
|
||||
Username string
|
||||
DisplayName string
|
||||
PfpFileID sql.NullInt64
|
||||
Bio string
|
||||
AuthenticationString string
|
||||
AuthenticationSalt string
|
||||
ID int
|
||||
Username string
|
||||
DisplayName string
|
||||
PfpFileID sql.NullInt64
|
||||
Bio string
|
||||
AuthenticationString string
|
||||
AuthenticationSalt string
|
||||
AuthenticationAlgorithm string
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
Verified bool
|
||||
Permissions int64
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
Verified bool
|
||||
Permissions int64
|
||||
}
|
||||
|
||||
const (
|
||||
// bcryptCost defines the work factor for bcrypt password hashing.
|
||||
// 12 is a reasonable default; increase for stronger machines.
|
||||
bcryptCost = 12
|
||||
)
|
||||
|
||||
func GetUserByID(db *sql.DB, id int) (*User, error) {
|
||||
query := "SELECT id, username, display_name, pfp_file_id, bio, authentication_string, authentication_salt, authentication_algorithm, created_at, updated_at, verified, permissions FROM users WHERE id = ?"
|
||||
row := db.QueryRow(query, id)
|
||||
|
|
@ -108,28 +117,42 @@ func GetUserByUsername(db *sql.DB, username string) (*User, error) {
|
|||
}
|
||||
|
||||
func CheckPassword(password, salt, algorithm, hash string) bool {
|
||||
if algorithm != "sha256" {
|
||||
switch algorithm {
|
||||
case "bcrypt":
|
||||
return bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) == nil
|
||||
case "sha256":
|
||||
computedHash := HashPassword(password, salt, algorithm)
|
||||
return computedHash == hash
|
||||
default:
|
||||
return false
|
||||
}
|
||||
computedHash := HashPassword(password, salt, algorithm)
|
||||
return computedHash == hash
|
||||
}
|
||||
|
||||
func HashPassword(password, salt, algorithm string) string {
|
||||
if algorithm != "sha256" {
|
||||
switch algorithm {
|
||||
case "sha256":
|
||||
data := password + salt
|
||||
hash := sha256.Sum256([]byte(data))
|
||||
return fmt.Sprintf("%x", hash)
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
data := password + salt
|
||||
hash := sha256.Sum256([]byte(data))
|
||||
return fmt.Sprintf("%x", hash)
|
||||
}
|
||||
|
||||
func CreateUser(db *sql.DB, username, password string) error {
|
||||
salt := "random-salt" // Replace with secure random generation
|
||||
algorithm := "sha256"
|
||||
hash := HashPassword(password, salt, algorithm)
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcryptCost)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Keep salt column for backward compatibility, or else this apparently shits itself
|
||||
var saltBytes [16]byte
|
||||
if _, err := rand.Read(saltBytes[:]); err != nil {
|
||||
return fmt.Errorf("failed to generate salt: %w", err)
|
||||
}
|
||||
salt := fmt.Sprintf("%x", saltBytes)
|
||||
|
||||
query := "INSERT INTO users (username, authentication_string, authentication_salt, authentication_algorithm, created_at, updated_at, verified, permissions) VALUES (?, ?, ?, ?, NOW(), NOW(), ?, 0)"
|
||||
_, err := db.Exec(query, username, hash, salt, algorithm, false)
|
||||
_, err = db.Exec(query, username, string(hash), salt, "bcrypt", false)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue