using bcrypt

jocadbz
Joca 2025-12-07 21:30:23 -03:00
parent 7b934e00a6
commit 876ac33d1b
Signed by: jocadbz
GPG Key ID: B1836DCE2F50BDF7
1 changed files with 46 additions and 23 deletions

View File

@ -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
}