DB migration & timer token

This commit is contained in:
2024-04-16 22:48:07 +02:00
parent 9da246e91e
commit 4e715ab1e1
8 changed files with 97 additions and 39 deletions

104
timer.go
View File

@ -20,16 +20,34 @@ import (
"stevenlr.com/timer/view"
)
func generateRandomString(len int) (string, error) {
bin := make([]byte, len)
_, err := rand.Read(bin)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(bin), nil
}
func generateSessionId() (string, error) {
return generateRandomString(66)
}
func generateTimerToken() (string, error) {
return generateRandomString(66)
}
func insertTimer(tx *sql.Tx, name string, seconds int, ownerId model.UUID) error {
now := model.MakeTimeNow()
end := model.Time(time.Time(now).Add(time.Duration(seconds) * time.Second))
id := model.MakeUUID()
token, _ := generateTimerToken()
_, err := tx.Exec(`
INSERT INTO Timer VALUES ($1, $2, $3, $4, $5)`, id, name, now, end, ownerId)
INSERT INTO Timer VALUES ($1, $2, $3, $4, $5, $6)`, id, name, now, end, ownerId, token)
return err
}
func initializeDatabase(db *sql.DB) error {
func initializeDatabaseV1(db *sql.DB) error {
tx, err := db.Begin()
if err != nil {
return err
@ -48,19 +66,13 @@ func initializeDatabase(db *sql.DB) error {
StartTime TEXT NOT NULL,
EndTime TEXT NOT NULL,
Owner BLOB NOT NULL,
PRIMARY KEY (id)
Token TEXT NOT NULL UNIQUE,
PRIMARY KEY (Id)
)`)
if err != nil {
return err
}
userUuidStr := "7015cee7-89a5-4057-b7c9-7e0128ad5086"
var userId model.UUID
err = userId.Scan(userUuidStr)
if err != nil {
return err
}
_, err = tx.Exec(`
CREATE TABLE User (
Id BLOB NOT NULL UNIQUE,
@ -73,14 +85,19 @@ func initializeDatabase(db *sql.DB) error {
return err
}
userPasswordClear := "steven"
password, err := bcrypt.GenerateFromPassword([]byte(userUuidStr+userPasswordClear), bcrypt.MinCost)
userName := "admin"
userPassword := "admin"
salt, err := generateRandomString(33)
if err != nil {
return err
}
_, err = tx.Exec(`INSERT INTO User VALUES ($1, $2, $3, $4)`, userId, "steven", userUuidStr, password)
password, err := bcrypt.GenerateFromPassword([]byte(salt+userPassword), bcrypt.MinCost)
if err != nil {
return err
}
_, err = tx.Exec(`INSERT INTO User VALUES ($1, $2, $3, $4)`, model.MakeUUID(), userName, salt, password)
if err != nil {
return err
}
@ -88,6 +105,50 @@ func initializeDatabase(db *sql.DB) error {
return tx.Commit()
}
func migrateDatabaseV2(db *sql.DB) error {
tx, err := db.Begin()
if err != nil {
return err
}
defer tx.Rollback()
_, err = tx.Exec(`PRAGMA user_version = 2`)
if err != nil {
return err
}
_, err = tx.Exec("CREATE INDEX TimerTokenIndex ON Timer(Token)")
if err != nil {
return err
}
return tx.Commit()
}
func initializeDatabase(db *sql.DB) error {
initialVersion := 0
row := db.QueryRow("PRAGMA user_version")
row.Scan(&initialVersion)
if initialVersion < 1 {
log.Println("Initializing DB V1")
err := initializeDatabaseV1(db)
if err != nil {
return err
}
}
if initialVersion < 2 {
log.Println("Migrating DB to V2")
err := migrateDatabaseV2(db)
if err != nil {
return err
}
}
return nil
}
func queryAllTimers(db *sql.DB, owner model.UUID) []model.Timer {
rows, err := db.Query("SELECT Id, Name FROM Timer WHERE Owner=$1", owner)
if err != nil {
@ -135,10 +196,10 @@ func queryTimer(db *sql.DB, idStr string, userId model.UUID) *model.Timer {
return nil
}
row := db.QueryRow("SELECT Id, Name, StartTime, EndTime, Owner FROM Timer WHERE Id=$1 AND Owner=$2", id, userId)
row := db.QueryRow("SELECT Id, Name, StartTime, EndTime, Owner, Token FROM Timer WHERE Id=$1 AND Owner=$2", id, userId)
var t model.Timer
if err := row.Scan(&t.Id, &t.Name, &t.StartTime, &t.EndTime, &t.Owner); err == nil {
if err := row.Scan(&t.Id, &t.Name, &t.StartTime, &t.EndTime, &t.Owner, &t.Token); err == nil {
return &t
}
@ -372,15 +433,6 @@ func (server *MyServer) handlePutTimer(w http.ResponseWriter, r *http.Request) {
view.TimersList(timers, user != nil).Render(context.Background(), w)
}
func generateSessionId() (string, error) {
bin := make([]byte, 64)
_, err := rand.Read(bin)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(bin), nil
}
func (server *MyServer) handlePostLogin(w http.ResponseWriter, r *http.Request) {
if server.findCurrentUser(w, r) != nil {
w.Header().Add("HX-Redirect", "/")
@ -433,7 +485,7 @@ func (server *MyServer) handlePostLogout(w http.ResponseWriter, r *http.Request)
func main() {
log.Println("Starting...")
db, err := sql.Open("sqlite3", ":memory:")
db, err := sql.Open("sqlite3", "file:timer.db")
if err != nil {
log.Fatalln(err)
}