mirror of
https://github.com/writefreely/writefreely
synced 2024-09-20 21:51:54 +00:00
Create blog during config for single-user blogs
This commit is contained in:
parent
486fb665ad
commit
a6478f1b1d
3 changed files with 127 additions and 60 deletions
49
app.go
49
app.go
|
@ -11,6 +11,7 @@ import (
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"regexp"
|
"regexp"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/gorilla/schema"
|
"github.com/gorilla/schema"
|
||||||
|
@ -127,6 +128,8 @@ func Serve() {
|
||||||
|
|
||||||
debugging = *debugPtr
|
debugging = *debugPtr
|
||||||
|
|
||||||
|
app := &app{}
|
||||||
|
|
||||||
if *createConfig {
|
if *createConfig {
|
||||||
log.Info("Creating configuration...")
|
log.Info("Creating configuration...")
|
||||||
c := config.New()
|
c := config.New()
|
||||||
|
@ -138,11 +141,31 @@ func Serve() {
|
||||||
}
|
}
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
} else if *doConfig {
|
} else if *doConfig {
|
||||||
err := config.Configure()
|
d, err := config.Configure()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Unable to configure: %v", err)
|
log.Error("Unable to configure: %v", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
if d != nil {
|
||||||
|
app.cfg = d.Config
|
||||||
|
connectToDatabase(app)
|
||||||
|
defer shutdown(app)
|
||||||
|
|
||||||
|
u := &User{
|
||||||
|
Username: d.User.Username,
|
||||||
|
HashedPass: d.User.HashedPass,
|
||||||
|
Created: time.Now().Truncate(time.Second).UTC(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create blog
|
||||||
|
log.Info("Creating user %s...\n", u.Username)
|
||||||
|
err = app.db.CreateUser(u, app.cfg.App.SiteName)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Unable to create user: %s", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
log.Info("Done!")
|
||||||
|
}
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,9 +177,7 @@ func Serve() {
|
||||||
log.Error("Unable to load configuration: %v", err)
|
log.Error("Unable to load configuration: %v", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
app := &app{
|
app.cfg = cfg
|
||||||
cfg: cfg,
|
|
||||||
}
|
|
||||||
|
|
||||||
hostName = cfg.App.Host
|
hostName = cfg.App.Host
|
||||||
isSingleUser = cfg.App.SingleUser
|
isSingleUser = cfg.App.SingleUser
|
||||||
|
@ -193,15 +214,8 @@ func Serve() {
|
||||||
app.cfg.Database.Database = "writeas"
|
app.cfg.Database.Database = "writeas"
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Connecting to database...")
|
connectToDatabase(app)
|
||||||
db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=true", app.cfg.Database.User, app.cfg.Database.Password, app.cfg.Database.Host, app.cfg.Database.Port, app.cfg.Database.Database))
|
|
||||||
if err != nil {
|
|
||||||
log.Error("\n%s\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
app.db = &datastore{db}
|
|
||||||
defer shutdown(app)
|
defer shutdown(app)
|
||||||
app.db.SetMaxOpenConns(50)
|
|
||||||
|
|
||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
handler := NewHandler(app)
|
handler := NewHandler(app)
|
||||||
|
@ -238,6 +252,17 @@ func Serve() {
|
||||||
http.ListenAndServe(fmt.Sprintf(":%d", app.cfg.Server.Port), nil)
|
http.ListenAndServe(fmt.Sprintf(":%d", app.cfg.Server.Port), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func connectToDatabase(app *app) {
|
||||||
|
log.Info("Connecting to database...")
|
||||||
|
db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=true", app.cfg.Database.User, app.cfg.Database.Password, app.cfg.Database.Host, app.cfg.Database.Port, app.cfg.Database.Database))
|
||||||
|
if err != nil {
|
||||||
|
log.Error("%s", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
app.db = &datastore{db}
|
||||||
|
app.db.SetMaxOpenConns(50)
|
||||||
|
}
|
||||||
|
|
||||||
func shutdown(app *app) {
|
func shutdown(app *app) {
|
||||||
log.Info("Closing database connection...")
|
log.Info("Closing database connection...")
|
||||||
app.db.Close()
|
app.db.Close()
|
||||||
|
|
6
config/data.go
Normal file
6
config/data.go
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
type UserCreation struct {
|
||||||
|
Username string
|
||||||
|
HashedPass []byte
|
||||||
|
}
|
132
config/setup.go
132
config/setup.go
|
@ -5,15 +5,24 @@ import (
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
"github.com/manifoldco/promptui"
|
"github.com/manifoldco/promptui"
|
||||||
"github.com/mitchellh/go-wordwrap"
|
"github.com/mitchellh/go-wordwrap"
|
||||||
|
"github.com/writeas/web-core/auth"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Configure() error {
|
type SetupData struct {
|
||||||
c, err := Load()
|
User *UserCreation
|
||||||
|
Config *Config
|
||||||
|
}
|
||||||
|
|
||||||
|
func Configure() (*SetupData, error) {
|
||||||
|
data := &SetupData{}
|
||||||
|
var err error
|
||||||
|
|
||||||
|
data.Config, err = Load()
|
||||||
var action string
|
var action string
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("No configuration yet. Creating new.")
|
fmt.Println("No configuration yet. Creating new.")
|
||||||
c = New()
|
data.Config = New()
|
||||||
action = "generate"
|
action = "generate"
|
||||||
} else {
|
} else {
|
||||||
fmt.Println("Configuration loaded.")
|
fmt.Println("Configuration loaded.")
|
||||||
|
@ -42,13 +51,13 @@ func Configure() error {
|
||||||
Templates: tmpls,
|
Templates: tmpls,
|
||||||
Label: "Local port",
|
Label: "Local port",
|
||||||
Validate: validatePort,
|
Validate: validatePort,
|
||||||
Default: fmt.Sprintf("%d", c.Server.Port),
|
Default: fmt.Sprintf("%d", data.Config.Server.Port),
|
||||||
}
|
}
|
||||||
port, err := prompt.Run()
|
port, err := prompt.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return data, err
|
||||||
}
|
}
|
||||||
c.Server.Port, _ = strconv.Atoi(port) // Ignore error, as we've already validated number
|
data.Config.Server.Port, _ = strconv.Atoi(port) // Ignore error, as we've already validated number
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
title(" Database setup ")
|
title(" Database setup ")
|
||||||
|
@ -58,58 +67,58 @@ func Configure() error {
|
||||||
Templates: tmpls,
|
Templates: tmpls,
|
||||||
Label: "Username",
|
Label: "Username",
|
||||||
Validate: validateNonEmpty,
|
Validate: validateNonEmpty,
|
||||||
Default: c.Database.User,
|
Default: data.Config.Database.User,
|
||||||
}
|
}
|
||||||
c.Database.User, err = prompt.Run()
|
data.Config.Database.User, err = prompt.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return data, err
|
||||||
}
|
}
|
||||||
|
|
||||||
prompt = promptui.Prompt{
|
prompt = promptui.Prompt{
|
||||||
Templates: tmpls,
|
Templates: tmpls,
|
||||||
Label: "Password",
|
Label: "Password",
|
||||||
Validate: validateNonEmpty,
|
Validate: validateNonEmpty,
|
||||||
Default: c.Database.Password,
|
Default: data.Config.Database.Password,
|
||||||
Mask: '*',
|
Mask: '*',
|
||||||
}
|
}
|
||||||
c.Database.Password, err = prompt.Run()
|
data.Config.Database.Password, err = prompt.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return data, err
|
||||||
}
|
}
|
||||||
|
|
||||||
prompt = promptui.Prompt{
|
prompt = promptui.Prompt{
|
||||||
Templates: tmpls,
|
Templates: tmpls,
|
||||||
Label: "Database name",
|
Label: "Database name",
|
||||||
Validate: validateNonEmpty,
|
Validate: validateNonEmpty,
|
||||||
Default: c.Database.Database,
|
Default: data.Config.Database.Database,
|
||||||
}
|
}
|
||||||
c.Database.Database, err = prompt.Run()
|
data.Config.Database.Database, err = prompt.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return data, err
|
||||||
}
|
}
|
||||||
|
|
||||||
prompt = promptui.Prompt{
|
prompt = promptui.Prompt{
|
||||||
Templates: tmpls,
|
Templates: tmpls,
|
||||||
Label: "Host",
|
Label: "Host",
|
||||||
Validate: validateNonEmpty,
|
Validate: validateNonEmpty,
|
||||||
Default: c.Database.Host,
|
Default: data.Config.Database.Host,
|
||||||
}
|
}
|
||||||
c.Database.Host, err = prompt.Run()
|
data.Config.Database.Host, err = prompt.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return data, err
|
||||||
}
|
}
|
||||||
|
|
||||||
prompt = promptui.Prompt{
|
prompt = promptui.Prompt{
|
||||||
Templates: tmpls,
|
Templates: tmpls,
|
||||||
Label: "Port",
|
Label: "Port",
|
||||||
Validate: validatePort,
|
Validate: validatePort,
|
||||||
Default: fmt.Sprintf("%d", c.Database.Port),
|
Default: fmt.Sprintf("%d", data.Config.Database.Port),
|
||||||
}
|
}
|
||||||
dbPort, err := prompt.Run()
|
dbPort, err := prompt.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return data, err
|
||||||
}
|
}
|
||||||
c.Database.Port, _ = strconv.Atoi(dbPort) // Ignore error, as we've already validated number
|
data.Config.Database.Port, _ = strconv.Atoi(dbPort) // Ignore error, as we've already validated number
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
title(" App setup ")
|
title(" App setup ")
|
||||||
|
@ -122,41 +131,68 @@ func Configure() error {
|
||||||
}
|
}
|
||||||
_, usersType, err := selPrompt.Run()
|
_, usersType, err := selPrompt.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return data, err
|
||||||
|
}
|
||||||
|
data.Config.App.SingleUser = usersType == "Single user blog"
|
||||||
|
|
||||||
|
if data.Config.App.SingleUser {
|
||||||
|
data.User = &UserCreation{}
|
||||||
|
|
||||||
|
// prompt for username
|
||||||
|
prompt = promptui.Prompt{
|
||||||
|
Templates: tmpls,
|
||||||
|
Label: "Admin username",
|
||||||
|
Validate: validateNonEmpty,
|
||||||
|
}
|
||||||
|
data.User.Username, err = prompt.Run()
|
||||||
|
if err != nil {
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// prompt for password
|
||||||
|
prompt = promptui.Prompt{
|
||||||
|
Templates: tmpls,
|
||||||
|
Label: "Admin password",
|
||||||
|
Validate: validateNonEmpty,
|
||||||
|
}
|
||||||
|
newUserPass, err := prompt.Run()
|
||||||
|
if err != nil {
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
data.User.HashedPass, err = auth.HashPass([]byte(newUserPass))
|
||||||
|
if err != nil {
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
c.App.SingleUser = usersType == "Single user"
|
|
||||||
// TODO: if c.App.SingleUser {
|
|
||||||
// prompt for username
|
|
||||||
// prompt for password
|
|
||||||
// create blog
|
|
||||||
|
|
||||||
siteNameLabel := "Instance name"
|
siteNameLabel := "Instance name"
|
||||||
if c.App.SingleUser {
|
if data.Config.App.SingleUser {
|
||||||
siteNameLabel = "Blog name"
|
siteNameLabel = "Blog name"
|
||||||
}
|
}
|
||||||
prompt = promptui.Prompt{
|
prompt = promptui.Prompt{
|
||||||
Templates: tmpls,
|
Templates: tmpls,
|
||||||
Label: siteNameLabel,
|
Label: siteNameLabel,
|
||||||
Validate: validateNonEmpty,
|
Validate: validateNonEmpty,
|
||||||
Default: c.App.SiteName,
|
Default: data.Config.App.SiteName,
|
||||||
}
|
}
|
||||||
c.App.SiteName, err = prompt.Run()
|
data.Config.App.SiteName, err = prompt.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return data, err
|
||||||
}
|
}
|
||||||
|
|
||||||
prompt = promptui.Prompt{
|
prompt = promptui.Prompt{
|
||||||
Templates: tmpls,
|
Templates: tmpls,
|
||||||
Label: "Public URL",
|
Label: "Public URL",
|
||||||
Validate: validateDomain,
|
Validate: validateDomain,
|
||||||
Default: c.App.Host,
|
Default: data.Config.App.Host,
|
||||||
}
|
}
|
||||||
c.App.Host, err = prompt.Run()
|
data.Config.App.Host, err = prompt.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return data, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !c.App.SingleUser {
|
if !data.Config.App.SingleUser {
|
||||||
selPrompt = promptui.Select{
|
selPrompt = promptui.Select{
|
||||||
Templates: selTmpls,
|
Templates: selTmpls,
|
||||||
Label: "Registration",
|
Label: "Registration",
|
||||||
|
@ -164,20 +200,20 @@ func Configure() error {
|
||||||
}
|
}
|
||||||
_, regType, err := selPrompt.Run()
|
_, regType, err := selPrompt.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return data, err
|
||||||
}
|
}
|
||||||
c.App.OpenRegistration = regType == "Open"
|
data.Config.App.OpenRegistration = regType == "Open"
|
||||||
|
|
||||||
prompt = promptui.Prompt{
|
prompt = promptui.Prompt{
|
||||||
Templates: tmpls,
|
Templates: tmpls,
|
||||||
Label: "Max blogs per user",
|
Label: "Max blogs per user",
|
||||||
Default: fmt.Sprintf("%d", c.App.MaxBlogs),
|
Default: fmt.Sprintf("%d", data.Config.App.MaxBlogs),
|
||||||
}
|
}
|
||||||
maxBlogs, err := prompt.Run()
|
maxBlogs, err := prompt.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return data, err
|
||||||
}
|
}
|
||||||
c.App.MaxBlogs, _ = strconv.Atoi(maxBlogs) // Ignore error, as we've already validated number
|
data.Config.App.MaxBlogs, _ = strconv.Atoi(maxBlogs) // Ignore error, as we've already validated number
|
||||||
}
|
}
|
||||||
|
|
||||||
selPrompt = promptui.Select{
|
selPrompt = promptui.Select{
|
||||||
|
@ -187,11 +223,11 @@ func Configure() error {
|
||||||
}
|
}
|
||||||
_, fedType, err := selPrompt.Run()
|
_, fedType, err := selPrompt.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return data, err
|
||||||
}
|
}
|
||||||
c.App.Federation = fedType == "Enabled"
|
data.Config.App.Federation = fedType == "Enabled"
|
||||||
|
|
||||||
if c.App.Federation {
|
if data.Config.App.Federation {
|
||||||
selPrompt = promptui.Select{
|
selPrompt = promptui.Select{
|
||||||
Templates: selTmpls,
|
Templates: selTmpls,
|
||||||
Label: "Federation usage stats",
|
Label: "Federation usage stats",
|
||||||
|
@ -199,9 +235,9 @@ func Configure() error {
|
||||||
}
|
}
|
||||||
_, fedStatsType, err := selPrompt.Run()
|
_, fedStatsType, err := selPrompt.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return data, err
|
||||||
}
|
}
|
||||||
c.App.PublicStats = fedStatsType == "Public"
|
data.Config.App.PublicStats = fedStatsType == "Public"
|
||||||
|
|
||||||
selPrompt = promptui.Select{
|
selPrompt = promptui.Select{
|
||||||
Templates: selTmpls,
|
Templates: selTmpls,
|
||||||
|
@ -210,10 +246,10 @@ func Configure() error {
|
||||||
}
|
}
|
||||||
_, fedStatsType, err = selPrompt.Run()
|
_, fedStatsType, err = selPrompt.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return data, err
|
||||||
}
|
}
|
||||||
c.App.Private = fedStatsType == "Private"
|
data.Config.App.Private = fedStatsType == "Private"
|
||||||
}
|
}
|
||||||
|
|
||||||
return Save(c)
|
return data, Save(data.Config)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue