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,10 +1,13 @@
package models
import (
"crypto/rand"
"crypto/sha256"
"database/sql"
"fmt"
"time"
"golang.org/x/crypto/bcrypt"
)
type User struct {
@ -22,6 +25,12 @@ type User struct {
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" {
return false
}
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
}
}
func HashPassword(password, salt, algorithm string) string {
if algorithm != "sha256" {
return ""
}
switch algorithm {
case "sha256":
data := password + salt
hash := sha256.Sum256([]byte(data))
return fmt.Sprintf("%x", hash)
default:
return ""
}
}
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
}