161 lines
5.2 KiB
Go
161 lines
5.2 KiB
Go
package models
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"database/sql"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
type User struct {
|
|
ID int
|
|
Username string
|
|
DisplayName string
|
|
PfpURL string
|
|
Bio string
|
|
AuthenticationString string
|
|
AuthenticationSalt string
|
|
AuthenticationAlgorithm string
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
Verified bool
|
|
Permissions int64
|
|
}
|
|
|
|
func GetUserByID(db *sql.DB, id int) (*User, error) {
|
|
query := "SELECT id, username, display_name, pfp_url, bio, authentication_string, authentication_salt, authentication_algorithm, created_at, updated_at, verified, permissions FROM users WHERE id = ?"
|
|
row := db.QueryRow(query, id)
|
|
user := &User{}
|
|
var displayName sql.NullString
|
|
var pfpURL sql.NullString
|
|
var bio sql.NullString
|
|
var createdAtString sql.NullString
|
|
var updatedAtString sql.NullString
|
|
err := row.Scan(&user.ID, &user.Username, &displayName, &pfpURL, &bio, &user.AuthenticationString, &user.AuthenticationSalt, &user.AuthenticationAlgorithm, &createdAtString, &updatedAtString, &user.Verified, &user.Permissions)
|
|
if err == sql.ErrNoRows {
|
|
return nil, nil
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if displayName.Valid {
|
|
user.DisplayName = displayName.String
|
|
} else {
|
|
user.DisplayName = ""
|
|
}
|
|
if pfpURL.Valid {
|
|
user.PfpURL = pfpURL.String
|
|
} else {
|
|
user.PfpURL = ""
|
|
}
|
|
if bio.Valid {
|
|
user.Bio = bio.String
|
|
} else {
|
|
user.Bio = ""
|
|
}
|
|
if createdAtString.Valid {
|
|
user.CreatedAt, err = time.Parse("2006-01-02 15:04:05", createdAtString.String)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error parsing created_at: %v", err)
|
|
}
|
|
} else {
|
|
user.CreatedAt = time.Time{}
|
|
}
|
|
if updatedAtString.Valid {
|
|
user.UpdatedAt, err = time.Parse("2006-01-02 15:04:05", updatedAtString.String)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error parsing updated_at: %v", err)
|
|
}
|
|
} else {
|
|
user.UpdatedAt = time.Time{}
|
|
}
|
|
return user, nil
|
|
}
|
|
|
|
func GetUserByUsername(db *sql.DB, username string) (*User, error) {
|
|
query := "SELECT id, username, display_name, pfp_url, bio, authentication_string, authentication_salt, authentication_algorithm, created_at, updated_at, verified, permissions FROM users WHERE username = ?"
|
|
row := db.QueryRow(query, username)
|
|
user := &User{}
|
|
var displayName sql.NullString
|
|
var pfpURL sql.NullString
|
|
var bio sql.NullString
|
|
var createdAtString sql.NullString
|
|
var updatedAtString sql.NullString
|
|
err := row.Scan(&user.ID, &user.Username, &displayName, &pfpURL, &bio, &user.AuthenticationString, &user.AuthenticationSalt, &user.AuthenticationAlgorithm, &createdAtString, &updatedAtString, &user.Verified, &user.Permissions)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if displayName.Valid {
|
|
user.DisplayName = displayName.String
|
|
} else {
|
|
user.DisplayName = ""
|
|
}
|
|
if pfpURL.Valid {
|
|
user.PfpURL = pfpURL.String
|
|
} else {
|
|
user.PfpURL = ""
|
|
}
|
|
if bio.Valid {
|
|
user.Bio = bio.String
|
|
} else {
|
|
user.Bio = ""
|
|
}
|
|
if createdAtString.Valid {
|
|
user.CreatedAt, err = time.Parse("2006-01-02 15:04:05", createdAtString.String)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error parsing created_at: %v", err)
|
|
}
|
|
} else {
|
|
user.CreatedAt = time.Time{}
|
|
}
|
|
if updatedAtString.Valid {
|
|
user.UpdatedAt, err = time.Parse("2006-01-02 15:04:05", updatedAtString.String)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error parsing updated_at: %v", err)
|
|
}
|
|
} else {
|
|
user.UpdatedAt = time.Time{}
|
|
}
|
|
return user, nil
|
|
}
|
|
|
|
func CheckPassword(password, salt, algorithm, hash string) bool {
|
|
if algorithm != "sha256" {
|
|
return false
|
|
}
|
|
computedHash := HashPassword(password, salt, algorithm)
|
|
return computedHash == hash
|
|
}
|
|
|
|
func HashPassword(password, salt, algorithm string) string {
|
|
if algorithm != "sha256" {
|
|
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)
|
|
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)
|
|
return err
|
|
}
|
|
|
|
func UpdateUserProfile(db *sql.DB, userID int, displayName, pfpURL, bio string) error {
|
|
query := "UPDATE users SET display_name = ?, pfp_url = ?, bio = ?, updated_at = NOW() WHERE id = ?"
|
|
_, err := db.Exec(query, displayName, pfpURL, bio, userID)
|
|
return err
|
|
}
|
|
|
|
const (
|
|
PermCreateBoard int64 = 1 << 0
|
|
PermManageUsers int64 = 1 << 1
|
|
)
|
|
|
|
func HasGlobalPermission(user *User, perm int64) bool {
|
|
return user.Permissions&perm != 0
|
|
} |