Ask admin credentials on initialize instead of defining them on config.json

master
Joca 2025-06-14 19:34:34 -03:00
parent 034b5cb13e
commit df5bb16000
Signed by: jocadbz
GPG Key ID: B1836DCE2F50BDF7
5 changed files with 91 additions and 56 deletions

View File

@ -4,7 +4,5 @@
"db_username": "threadr_user", "db_username": "threadr_user",
"db_password": "threadr_password", "db_password": "threadr_password",
"db_database": "threadr_db", "db_database": "threadr_db",
"db_svr_host": "localhost:3306", "db_svr_host": "localhost:3306"
"admin_username": "admin",
"admin_password": "adminpassword"
} }

2
go.mod
View File

@ -11,4 +11,6 @@ require (
require ( require (
filippo.io/edwards25519 v1.1.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect github.com/gorilla/securecookie v1.1.2 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/term v0.32.0 // indirect
) )

4
go.sum
View File

@ -10,3 +10,7 @@ github.com/gorilla/sessions v1.4.0 h1:kpIYOp/oi6MG/p5PgxApU8srsSw9tuFbt46Lt7auzq
github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2emc7lT5ik= github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2emc7lT5ik=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=

View File

@ -19,14 +19,12 @@ type PageData struct {
} }
type Config struct { type Config struct {
DomainName string `json:"domain_name"` DomainName string `json:"domain_name"`
ThreadrDir string `json:"threadr_dir"` ThreadrDir string `json:"threadr_dir"`
DBUsername string `json:"db_username"` DBUsername string `json:"db_username"`
DBPassword string `json:"db_password"` DBPassword string `json:"db_password"`
DBDatabase string `json:"db_database"` DBDatabase string `json:"db_database"`
DBServerHost string `json:"db_svr_host"` DBServerHost string `json:"db_svr_host"`
AdminUsername string `json:"admin_username"`
AdminPassword string `json:"admin_password"`
} }
type App struct { type App struct {
@ -77,4 +75,4 @@ func (app *App) RequireLoginMW(next http.HandlerFunc) http.HandlerFunc {
} }
next(w, r) next(w, r)
} }
} }

121
main.go
View File

@ -1,20 +1,24 @@
package main package main
import ( import (
"database/sql" "bufio"
"encoding/json" "database/sql"
"flag" "encoding/json"
"fmt" "flag"
"html/template" "fmt"
"log" "html/template"
"net/http" "log"
"os" "net/http"
"path/filepath" "os"
"threadr/handlers" "path/filepath"
"threadr/models" "strings"
"syscall"
"threadr/handlers"
"threadr/models"
"github.com/gorilla/sessions" _ "github.com/go-sql-driver/mysql"
_ "github.com/go-sql-driver/mysql" "github.com/gorilla/sessions"
"golang.org/x/term"
) )
func loadConfig(filename string) (*handlers.Config, error) { func loadConfig(filename string) (*handlers.Config, error) {
@ -199,37 +203,66 @@ func createTablesIfNotExist(db *sql.DB) error {
return nil return nil
} }
func ensureAdminUser(db *sql.DB, config *handlers.Config) error { func ensureAdminUser(db *sql.DB) error {
adminUser, err := models.GetUserByUsername(db, config.AdminUsername) reader := bufio.NewReader(os.Stdin)
if err != nil && err != sql.ErrNoRows {
return fmt.Errorf("error checking for admin user: %v", err)
}
// If admin user doesn't exist, create one // Get username
if adminUser == nil { fmt.Print("Enter admin username: ")
log.Printf("Creating admin user: %s", config.AdminUsername) username, _ := reader.ReadString('\n')
err = models.CreateUser(db, config.AdminUsername, config.AdminPassword) username = strings.TrimSpace(username)
if err != nil {
return fmt.Errorf("error creating admin user: %v", err) // Check if user already exists
} existingUser, err := models.GetUserByUsername(db, username)
if err != nil && err != sql.ErrNoRows {
// Get the newly created admin user to update permissions return fmt.Errorf("error checking for admin user: %v", err)
adminUser, err = models.GetUserByUsername(db, config.AdminUsername) }
if err != nil { if existingUser != nil {
return fmt.Errorf("error fetching new admin user: %v", err) return fmt.Errorf("user '%s' already exists", username)
} }
// Set admin permissions (all permissions) // Get password
_, err = db.Exec("UPDATE users SET permissions = ? WHERE id = ?", fmt.Print("Enter admin password: ")
models.PermCreateBoard|models.PermManageUsers, adminUser.ID) bytePassword, err := term.ReadPassword(int(syscall.Stdin))
if err != nil { if err != nil {
return fmt.Errorf("error setting admin permissions: %v", err) return fmt.Errorf("error reading password: %v", err)
} }
log.Println("Admin user created successfully with full permissions") password := string(bytePassword)
} else { fmt.Println() // Newline after password input
log.Println("Admin user already exists")
} // Confirm password
return nil fmt.Print("Confirm admin password: ")
bytePasswordConfirm, err := term.ReadPassword(int(syscall.Stdin))
if err != nil {
return fmt.Errorf("error reading password confirmation: %v", err)
}
passwordConfirm := string(bytePasswordConfirm)
fmt.Println()
if password != passwordConfirm {
return fmt.Errorf("passwords do not match")
}
// Create user
log.Printf("Creating admin user: %s", username)
err = models.CreateUser(db, username, password)
if err != nil {
return fmt.Errorf("error creating admin user: %v", err)
}
// Get the newly created admin user to update permissions
adminUser, err := models.GetUserByUsername(db, username)
if err != nil {
return fmt.Errorf("error fetching new admin user: %v", err)
}
// Set admin permissions (all permissions)
_, err = db.Exec("UPDATE users SET permissions = ? WHERE id = ?",
models.PermCreateBoard|models.PermManageUsers, adminUser.ID)
if err != nil {
return fmt.Errorf("error setting admin permissions: %v", err)
}
log.Println("Admin user created successfully with full permissions")
return nil
} }
func main() { func main() {
@ -258,7 +291,7 @@ func main() {
log.Fatal("Error creating database tables:", err) log.Fatal("Error creating database tables:", err)
} }
err = ensureAdminUser(db, config) err = ensureAdminUser(db)
if err != nil { if err != nil {
log.Fatal("Error ensuring admin user:", err) log.Fatal("Error ensuring admin user:", err)
} }