allow specifying detai;s for initial admin user

This commit is contained in:
Steffen Vogel 2020-11-13 09:33:43 +01:00
parent e2624f64ed
commit bd00442940
4 changed files with 91 additions and 33 deletions

View file

@ -23,9 +23,10 @@ package configuration
import ( import (
"flag" "flag"
"github.com/zpatrick/go-config"
"log" "log"
"os" "os"
"github.com/zpatrick/go-config"
) )
// Global configuration // Global configuration
@ -50,6 +51,9 @@ func InitConfig() error {
port = flag.String("port", "4000", "Port of the backend (default is 4000)") port = flag.String("port", "4000", "Port of the backend (default is 4000)")
baseHost = flag.String("base-host", "localhost:4000", "The host at which the backend is hosted (default: localhost)") baseHost = flag.String("base-host", "localhost:4000", "The host at which the backend is hosted (default: localhost)")
basePath = flag.String("base-path", "/api/v2", "The path at which the API routes are located (default /api/v2)") basePath = flag.String("base-path", "/api/v2", "The path at which the API routes are located (default /api/v2)")
adminUser = flag.String("admin-user", "", "Initial admin username")
adminPass = flag.String("admin-pass", "", "Initial admin password")
adminMail = flag.String("admin-mail", "", "Initial admin mail address")
) )
flag.Parse() flag.Parse()
@ -66,6 +70,9 @@ func InitConfig() error {
"port": *port, "port": *port,
"base.host": *baseHost, "base.host": *baseHost,
"base.path": *basePath, "base.path": *basePath,
"admin.user": *adminUser,
"admin.pass": *adminPass,
"admin.mail": *adminMail,
} }
mappings := map[string]string{ mappings := map[string]string{
@ -81,6 +88,9 @@ func InitConfig() error {
"BASE_PATH": "base.path", "BASE_PATH": "base.path",
"MODE": "mode", "MODE": "mode",
"PORT": "port", "PORT": "port",
"ADMIN_USER": "admin.user",
"ADMIN_PASS": "admin.pass",
"ADMIN_MAIL": "admin.mail",
} }
defaults := config.NewStatic(static) defaults := config.NewStatic(static)
@ -151,5 +161,4 @@ func ConfigureBackend() (string, string, string, string, string, string, string,
AMQPpass, _ := GolbalConfig.String("amqp.pass") AMQPpass, _ := GolbalConfig.String("amqp.pass")
return mode, baseHost, basePath, port, AMQPhost, AMQPuser, AMQPpass, nil return mode, baseHost, basePath, port, AMQPhost, AMQPuser, AMQPpass, nil
} }

View file

@ -24,10 +24,14 @@ package helper
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"math/rand"
"strings"
"time"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database" "git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
"github.com/jinzhu/gorm/dialects/postgres" "github.com/jinzhu/gorm/dialects/postgres"
"github.com/zpatrick/go-config"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
"time"
) )
// ####################################################################### // #######################################################################
@ -321,8 +325,22 @@ var WidgetE = database.Widget{
SignalIDs: []int64{}, SignalIDs: []int64{},
} }
// add a default admin user to the DB func generatePassword(Len int) string {
func DBAddAdminUser() error { rand.Seed(time.Now().UnixNano())
chars := []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
"abcdefghijklmnopqrstuvwxyz" +
"0123456789")
var b strings.Builder
for i := 0; i < Len; i++ {
b.WriteRune(chars[rand.Intn(len(chars))])
}
return b.String()
}
// DBAddAdminUser adds a default admin user to the DB
func DBAddAdminUser(cfg *config.Config) error {
database.DBpool.AutoMigrate(&database.User{}) database.DBpool.AutoMigrate(&database.User{})
// Check if admin user exists in DB // Check if admin user exists in DB
@ -331,10 +349,31 @@ func DBAddAdminUser() error {
if len(users) == 0 { if len(users) == 0 {
fmt.Println("No admin user found in DB, adding default admin user.") fmt.Println("No admin user found in DB, adding default admin user.")
//create a copy of global test data
user0 := User0 name, err := cfg.String("admin.user")
if err != nil || name == "" {
name = "admin"
}
pw, err := cfg.String("admin.pass")
if err != nil || pw == "" {
pw = generatePassword(16)
fmt.Printf(" Generated admin password: %s\n", pw)
}
mail, err := cfg.String("admin.mail")
if err == nil || mail == "" {
mail = "admin@example.com"
}
pwEnc, _ := bcrypt.GenerateFromPassword([]byte(pw), bcryptCost)
// create a copy of global test data
user := database.User{Username: name, Password: string(pwEnc),
Role: "Admin", Mail: mail, Active: true}
// add admin user to DB // add admin user to DB
err = database.DBpool.Create(&user0).Error err = database.DBpool.Create(&user).Error
} }
return err return err

View file

@ -25,6 +25,12 @@ package routes
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"io"
"mime/multipart"
"net/http"
"net/http/httptest"
"os"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database" "git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper" "git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
component_configuration "git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/component-configuration" component_configuration "git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/component-configuration"
@ -40,11 +46,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
ginSwagger "github.com/swaggo/gin-swagger" ginSwagger "github.com/swaggo/gin-swagger"
"github.com/swaggo/gin-swagger/swaggerFiles" "github.com/swaggo/gin-swagger/swaggerFiles"
"io" "github.com/zpatrick/go-config"
"mime/multipart"
"net/http"
"net/http/httptest"
"os"
) )
// register all backend endpoints; to be called after DB is initialized // register all backend endpoints; to be called after DB is initialized
@ -74,12 +76,18 @@ func RegisterEndpoints(router *gin.Engine, api *gin.RouterGroup) {
} }
// Uses API endpoints to add test data to the backend; All endpoints have to be registered before invoking this function. // Uses API endpoints to add test data to the backend; All endpoints have to be registered before invoking this function.
func AddTestData(basePath string, router *gin.Engine) (*bytes.Buffer, error) { func AddTestData(cfg *config.Config, router *gin.Engine) (*bytes.Buffer, error) {
basePath, err := cfg.String("base.path")
if err != nil {
fmt.Println("error: testdata could not be added to DB: no base path specified")
return nil, err
}
database.MigrateModels() database.MigrateModels()
// Create entries of each model (data defined in test_data.go) // Create entries of each model (data defined in test_data.go)
// add Admin user // add Admin user
err := helper.DBAddAdminUser() err = helper.DBAddAdminUser(cfg)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -23,6 +23,8 @@ package main
import ( import (
"fmt" "fmt"
"log"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/amqp" "git.rwth-aachen.de/acs/public/villas/web-backend-go/amqp"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration" "git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database" "git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
@ -30,23 +32,23 @@ import (
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper" "git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes" "git.rwth-aachen.de/acs/public/villas/web-backend-go/routes"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"log" "github.com/zpatrick/go-config"
) )
func addData(router *gin.Engine, mode string, basePath string) error { func addData(router *gin.Engine, cfg *config.Config) error {
if mode == "test" { if mode, err := cfg.String("mode"); err == nil && mode == "test" {
// test mode: drop all tables and add test data to DB // test mode: drop all tables and add test data to DB
database.DropTables() database.DropTables()
log.Println("Database tables dropped, using API to add test data") log.Println("Database tables dropped, using API to add test data")
resp, err := routes.AddTestData(basePath, router) resp, err := routes.AddTestData(cfg, router)
if err != nil { if err != nil {
fmt.Println("error: testdata could not be added to DB:", err.Error(), "Response body: ", resp) fmt.Println("error: testdata could not be added to DB:", err.Error(), "Response body: ", resp)
return err return err
} }
} else { } else {
// release mode: make sure that at least one admin user exists in DB // release mode: make sure that at least one admin user exists in DB
err := helper.DBAddAdminUser() err := helper.DBAddAdminUser(cfg)
if err != nil { if err != nil {
fmt.Println("error: adding admin user failed:", err.Error()) fmt.Println("error: adding admin user failed:", err.Error())
return err return err
@ -95,7 +97,7 @@ func main() {
apidocs.SwaggerInfo.BasePath = basePath apidocs.SwaggerInfo.BasePath = basePath
// add data to DB (if any) // add data to DB (if any)
err = addData(r, mode, basePath) err = addData(r, configuration.GolbalConfig)
if err != nil { if err != nil {
panic(err) panic(err)
} }