create admin account on first start

This commit is contained in:
Daniel Eder 2025-02-17 19:15:34 +01:00
parent 708722865d
commit 0e080dd391
5 changed files with 113 additions and 8 deletions

5
go.mod
View file

@ -2,4 +2,7 @@ module tms
go 1.22.0
require github.com/mattn/go-sqlite3 v1.14.24 // indirect
require (
github.com/mattn/go-sqlite3 v1.14.24 // indirect
golang.org/x/crypto v0.33.0
)

2
go.sum
View file

@ -1,2 +1,4 @@
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=

87
main.go
View file

@ -8,6 +8,8 @@ import (
"net/http"
"time"
"golang.org/x/crypto/bcrypt"
_ "github.com/mattn/go-sqlite3"
)
@ -300,16 +302,87 @@ func addTrainerHandler(w http.ResponseWriter, r *http.Request) {
}
func hashPassword(password string) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
return string(bytes), err
}
func setupAdminHandler(w http.ResponseWriter, r *http.Request) {
// Check if an admin exists
var count int
err := db.QueryRow("SELECT COUNT(*) FROM admins").Scan(&count)
if err != nil {
http.Error(w, "Database error", http.StatusInternalServerError)
return
}
// If an admin exists, redirect to login
if count > 0 {
http.Redirect(w, r, "/login", http.StatusSeeOther)
return
}
// If it's a POST request, create the admin
if r.Method == http.MethodPost {
name := r.FormValue("name")
email := r.FormValue("email")
password := r.FormValue("password")
if email == "" || password == "" || name == "" {
http.Error(w, "Name, email and password are required", http.StatusBadRequest)
return
}
// Hash the password
hashedPassword, err := hashPassword(password)
if err != nil {
http.Error(w, "Error hashing password", http.StatusInternalServerError)
return
}
// Insert the admin into the database
_, err = db.Exec("INSERT INTO admins (name, email, password) VALUES (?, ?, ?)", name, email, hashedPassword)
if err != nil {
http.Error(w, "Error saving admin", http.StatusInternalServerError)
return
}
// Redirect to login after setup
http.Redirect(w, r, "/login", http.StatusSeeOther)
return
}
// Show the admin setup page
err = tmpl.ExecuteTemplate(w, "setup_admin.html", nil)
if err != nil {
http.Error(w, "Template rendering error", http.StatusInternalServerError)
}
}
func redirectIfNoAdmin(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var count int
err := db.QueryRow("SELECT COUNT(*) FROM admins").Scan(&count)
if err != nil || count == 0 {
http.Redirect(w, r, "/setup-admin", http.StatusSeeOther)
return
}
next.ServeHTTP(w, r)
})
}
func main() {
initDB()
initTemplates()
http.HandleFunc("/", homeHandler)
http.HandleFunc("/trainings", trainingListHandler)
http.HandleFunc("/trainers", trainerListHandler)
http.HandleFunc("/trainers/add", addTrainerHandler)
http.HandleFunc("/training-areas", trainingAreaListHandler)
http.HandleFunc("/training-areas/add", addTrainingAreaHandler)
http.HandleFunc("/training-areas/assign-trainer", assignTrainerToAreaHandler)
http.Handle("/", redirectIfNoAdmin(http.HandlerFunc(homeHandler)))
http.Handle("/trainings", redirectIfNoAdmin(http.HandlerFunc(trainingListHandler)))
http.Handle("/trainers", redirectIfNoAdmin(http.HandlerFunc(trainerListHandler)))
http.Handle("/trainers/add", redirectIfNoAdmin(http.HandlerFunc(addTrainerHandler)))
http.Handle("/training-areas", redirectIfNoAdmin(http.HandlerFunc(trainingAreaListHandler)))
http.Handle("/training-areas/add", redirectIfNoAdmin(http.HandlerFunc(addTrainingAreaHandler)))
http.Handle("/training-areas/assign-trainer", redirectIfNoAdmin(http.HandlerFunc(assignTrainerToAreaHandler)))
http.HandleFunc("/setup-admin", setupAdminHandler)
fmt.Println("Server running on http://localhost:8080")
http.ListenAndServe(":8080", nil)

View file

@ -42,3 +42,10 @@ CREATE TABLE IF NOT EXISTS training_training_areas (
FOREIGN KEY (training_id) REFERENCES trainings(id),
FOREIGN KEY (training_area_id) REFERENCES training_areas(id)
);
CREATE TABLE IF NOT EXISTS admins (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
password TEXT NOT NULL
);

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
{{template "head.html" .}} <!-- Include header template -->
<body>
{{template "header.html" .}}
<h2>Setup Admin Account</h2>
<form method="post">
<label>Name:</label>
<input type="text", name="name" required><br>
<label>Email:</label>
<input type="email" name="email" required><br>
<label>Password:</label>
<input type="password" name="password" required><br>
<button type="submit">Create Admin</button>
</form>
</body>
</html>