Self-contained HTTP/HTTPS/TCP/UDP reverse proxy manager written in Go, with SQLite storage, a Bootstrap 5 admin UI (Go templates, no JS framework), and a REST API under /api/v1. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QTXFrNP1imCW7jtfL5SZrw
59 lines
1.6 KiB
Go
59 lines
1.6 KiB
Go
package database
|
|
|
|
import (
|
|
"database/sql"
|
|
"errors"
|
|
"time"
|
|
|
|
"github.com/owen/vibeproxy/internal/models"
|
|
)
|
|
|
|
var ErrNotFound = errors.New("not found")
|
|
|
|
const timeFmt = "2006-01-02T15:04:05.000Z"
|
|
|
|
func parseTime(s string) time.Time {
|
|
t, _ := time.Parse(timeFmt, s)
|
|
return t
|
|
}
|
|
|
|
func GetUserByUsername(db *sql.DB, username string) (*models.User, error) {
|
|
row := db.QueryRow(`SELECT id, username, password_hash, must_change_pw, created_at, updated_at FROM users WHERE username = ?`, username)
|
|
u := &models.User{}
|
|
var mustChange int
|
|
var created, updated string
|
|
if err := row.Scan(&u.ID, &u.Username, &u.PasswordHash, &mustChange, &created, &updated); err != nil {
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return nil, ErrNotFound
|
|
}
|
|
return nil, err
|
|
}
|
|
u.MustChangePW = mustChange == 1
|
|
u.CreatedAt = parseTime(created)
|
|
u.UpdatedAt = parseTime(updated)
|
|
return u, nil
|
|
}
|
|
|
|
func CountUsers(db *sql.DB) (int, error) {
|
|
var n int
|
|
err := db.QueryRow(`SELECT COUNT(*) FROM users`).Scan(&n)
|
|
return n, err
|
|
}
|
|
|
|
func CreateUser(db *sql.DB, username, passwordHash string, mustChange bool) error {
|
|
_, err := db.Exec(`INSERT INTO users (username, password_hash, must_change_pw) VALUES (?, ?, ?)`, username, passwordHash, boolToInt(mustChange))
|
|
return err
|
|
}
|
|
|
|
func UpdateUserPassword(db *sql.DB, username, passwordHash string, mustChange bool) error {
|
|
_, err := db.Exec(`UPDATE users SET password_hash = ?, must_change_pw = ?, updated_at = strftime('%Y-%m-%dT%H:%M:%fZ','now') WHERE username = ?`, passwordHash, boolToInt(mustChange), username)
|
|
return err
|
|
}
|
|
|
|
func boolToInt(b bool) int {
|
|
if b {
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|