lishwist/core/user.go

111 lines
2.6 KiB
Go

package lishwist
import (
"fmt"
"github.com/google/uuid"
"lishwist/core/internal/db"
"lishwist/core/internal/normalize"
)
type User struct {
Id string
NormalName string
Name string
Reference string
IsAdmin bool
IsLive bool
}
func queryManyUsers(query string, args ...any) ([]User, error) {
rows, err := db.Connection.Query(query, args...)
if err != nil {
return nil, err
}
defer rows.Close()
users := []User{}
for rows.Next() {
var u User
err = rows.Scan(&u.Id, &u.NormalName, &u.Name, &u.Reference, &u.IsAdmin, &u.IsLive)
if err != nil {
return nil, err
}
users = append(users, u)
}
err = rows.Err()
if err != nil {
return nil, err
}
return users, nil
}
func queryOneUser(query string, args ...any) (*User, error) {
users, err := queryManyUsers(query, args...)
if err != nil {
return nil, err
}
if len(users) < 1 {
return nil, nil
}
return &users[0], nil
}
func getUserByName(username string) (*User, error) {
username = normalize.Name(username)
stmt := "SELECT id, name, display_name, reference, is_admin, is_live FROM v_user WHERE name = ?"
return queryOneUser(stmt, username)
}
func createUser(name string, passHash []byte, isAdmin bool) (*User, error) {
username := normalize.Name(name)
stmt := "INSERT INTO user (name, display_name, reference, password_hash, is_admin) VALUES (?, ?, ?, ?, ?)"
reference, err := uuid.NewRandom()
if err != nil {
return nil, fmt.Errorf("Failed to generate reference: %w")
}
result, err := db.Connection.Exec(stmt, username, name, reference, passHash, isAdmin)
if err != nil {
return nil, fmt.Errorf("Failed to execute query: %w")
}
id, err := result.LastInsertId()
if err != nil {
return nil, fmt.Errorf("Failed to get last insert id: %w")
}
user := User{
Id: fmt.Sprintf("%d", id),
Name: name,
}
return &user, nil
}
func (u *User) getPassHash() ([]byte, error) {
stmt := "SELECT password_hash FROM v_user WHERE id = ?"
var passHash string
err := db.Connection.QueryRow(stmt, u.Id).Scan(&passHash)
if err != nil {
return nil, err
}
return []byte(passHash), nil
}
func getUserByReference(reference string) (*User, error) {
stmt := "SELECT id, name, display_name, reference, is_admin, is_live FROM v_user WHERE reference = ?"
return queryOneUser(stmt, reference)
}
func hasUsers() (bool, error) {
stmt := "SELECT COUNT(id) FROM v_user LIMIT 1"
var userCount uint
err := db.Connection.QueryRow(stmt).Scan(&userCount)
if err != nil {
return false, err
}
return userCount > 0, nil
}
func (*Admin) ListUsers() ([]User, error) {
stmt := "SELECT id, name, display_name, reference, is_admin, is_live FROM user"
return queryManyUsers(stmt)
}