diff --git a/config/config.json.sample b/config/config.json.sample index 54e1824..25c325f 100644 --- a/config/config.json.sample +++ b/config/config.json.sample @@ -4,7 +4,5 @@ "db_username": "threadr_user", "db_password": "threadr_password", "db_database": "threadr_db", - "db_svr_host": "localhost:3306", - "admin_username": "admin", - "admin_password": "adminpassword" + "db_svr_host": "localhost:3306" } diff --git a/go.mod b/go.mod index 188efa0..f39d814 100644 --- a/go.mod +++ b/go.mod @@ -11,4 +11,6 @@ require ( require ( filippo.io/edwards25519 v1.1.0 // 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 ) diff --git a/go.sum b/go.sum index 8d7d4ce..498ed04 100644 --- a/go.sum +++ b/go.sum @@ -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/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= 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= diff --git a/handlers/app.go b/handlers/app.go index ccf0060..20cca0e 100644 --- a/handlers/app.go +++ b/handlers/app.go @@ -19,14 +19,12 @@ type PageData struct { } type Config struct { - DomainName string `json:"domain_name"` - ThreadrDir string `json:"threadr_dir"` - DBUsername string `json:"db_username"` - DBPassword string `json:"db_password"` - DBDatabase string `json:"db_database"` - DBServerHost string `json:"db_svr_host"` - AdminUsername string `json:"admin_username"` - AdminPassword string `json:"admin_password"` + DomainName string `json:"domain_name"` + ThreadrDir string `json:"threadr_dir"` + DBUsername string `json:"db_username"` + DBPassword string `json:"db_password"` + DBDatabase string `json:"db_database"` + DBServerHost string `json:"db_svr_host"` } type App struct { @@ -77,4 +75,4 @@ func (app *App) RequireLoginMW(next http.HandlerFunc) http.HandlerFunc { } next(w, r) } -} \ No newline at end of file +} diff --git a/main.go b/main.go index f3195fd..3e37972 100644 --- a/main.go +++ b/main.go @@ -1,20 +1,24 @@ package main import ( - "database/sql" - "encoding/json" - "flag" - "fmt" - "html/template" - "log" - "net/http" - "os" - "path/filepath" - "threadr/handlers" - "threadr/models" + "bufio" + "database/sql" + "encoding/json" + "flag" + "fmt" + "html/template" + "log" + "net/http" + "os" + "path/filepath" + "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) { @@ -199,37 +203,66 @@ func createTablesIfNotExist(db *sql.DB) error { return nil } -func ensureAdminUser(db *sql.DB, config *handlers.Config) error { - adminUser, err := models.GetUserByUsername(db, config.AdminUsername) - if err != nil && err != sql.ErrNoRows { - return fmt.Errorf("error checking for admin user: %v", err) - } +func ensureAdminUser(db *sql.DB) error { + reader := bufio.NewReader(os.Stdin) - // If admin user doesn't exist, create one - if adminUser == nil { - log.Printf("Creating admin user: %s", config.AdminUsername) - err = models.CreateUser(db, config.AdminUsername, config.AdminPassword) - 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, config.AdminUsername) - 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") - } else { - log.Println("Admin user already exists") - } - return nil + // Get username + fmt.Print("Enter admin username: ") + username, _ := reader.ReadString('\n') + username = strings.TrimSpace(username) + + // Check if user already exists + existingUser, err := models.GetUserByUsername(db, username) + if err != nil && err != sql.ErrNoRows { + return fmt.Errorf("error checking for admin user: %v", err) + } + if existingUser != nil { + return fmt.Errorf("user '%s' already exists", username) + } + + // Get password + fmt.Print("Enter admin password: ") + bytePassword, err := term.ReadPassword(int(syscall.Stdin)) + if err != nil { + return fmt.Errorf("error reading password: %v", err) + } + password := string(bytePassword) + fmt.Println() // Newline after password input + + // Confirm password + 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() { @@ -258,7 +291,7 @@ func main() { log.Fatal("Error creating database tables:", err) } - err = ensureAdminUser(db, config) + err = ensureAdminUser(db) if err != nil { log.Fatal("Error ensuring admin user:", err) }