diff --git a/database/admin.go b/database/admin.go new file mode 100644 index 0000000..025301b --- /dev/null +++ b/database/admin.go @@ -0,0 +1,113 @@ +/** Package database +* +* @author Sonja Happ +* @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC +* @license GNU General Public License (version 3) +* +* VILLASweb-backend-go +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*********************************************************************************/ +package database + +import ( + "fmt" + "math/rand" + "strings" + "time" + + "github.com/zpatrick/go-config" + "golang.org/x/crypto/bcrypt" +) + +// AddAdminUser adds a default admin user to the DB +func AddAdminUser(cfg *config.Config) (string, error) { + DBpool.AutoMigrate(User{}) + + updatedPW := false + generatedPW := false + + adminName, _ := cfg.StringOr("admin.user", "admin") + adminMail, _ := cfg.StringOr("admin.mail", "admin@example.com") + adminPW, err := cfg.String("admin.pass") + if err == nil && adminPW != "" { + updatedPW = true + } else if err != nil || adminPW == "" { + adminPW = generatePassword(16) + generatedPW = true + } + + adminPWEnc, err := bcrypt.GenerateFromPassword([]byte(adminPW), 10) + if err != nil { + return "", err + } + + // Check if admin user exists in DB + var users []User + err = DBpool.Where("Username = ?", adminName).Find(&users).Error + if err != nil { + return "", err + } + + if len(users) == 0 { + fmt.Println("No admin user found in DB, adding default admin user.") + if generatedPW { + fmt.Printf(" Generated admin password: %s for admin user %s\n", adminPW, adminName) + } + + user := User{ + Username: adminName, + Password: string(adminPWEnc), + Role: "Admin", + Mail: adminMail, + Active: true, + } + + // add admin user to DB + err = DBpool.Create(&user).Error + if err != nil { + return "", err + } + } else if updatedPW { + fmt.Println("Found existing admin user in DB, updating user from CLI parameters.") + + user := users[0] + + user.Password = string(adminPWEnc) + user.Role = "Admin" + user.Mail = adminMail + user.Active = true + + err = DBpool.Model(user).Update(&user).Error + if err != nil { + return "", err + } + } + + return adminPW, err +} + +func generatePassword(Len int) string { + 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() +} diff --git a/database/database.go b/database/database.go index e0bc95f..ecff9e3 100644 --- a/database/database.go +++ b/database/database.go @@ -24,11 +24,6 @@ package database import ( "fmt" "log" - "math/rand" - "strings" - "time" - - "golang.org/x/crypto/bcrypt" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/postgres" @@ -123,61 +118,3 @@ func MigrateModels() { DBpool.AutoMigrate(&Widget{}) DBpool.AutoMigrate(&Result{}) } - -// DBAddAdminUser adds a default admin user to the DB -func DBAddAdminUser(cfg *config.Config) (string, error) { - DBpool.AutoMigrate(User{}) - - // Check if admin user exists in DB - var users []User - DBpool.Where("Role = ?", "Admin").Find(&users) - - adminPW := "" - - if len(users) == 0 { - fmt.Println("No admin user found in DB, adding default admin user.") - - adminName, err := cfg.String("admin.user") - if err != nil || adminName == "" { - adminName = "admin" - } - - adminPW, err = cfg.String("admin.pass") - if err != nil || adminPW == "" { - adminPW = generatePassword(16) - fmt.Printf(" Generated admin password: %s for admin user %s\n", adminPW, adminName) - } - - mail, err := cfg.String("admin.mail") - if err == nil || mail == "" { - mail = "admin@example.com" - } - - pwEnc, _ := bcrypt.GenerateFromPassword([]byte(adminPW), 10) - - // create a copy of global test data - user := User{Username: adminName, Password: string(pwEnc), - Role: "Admin", Mail: mail, Active: true} - - // add admin user to DB - err = DBpool.Create(&user).Error - if err != nil { - return "", err - } - } - return adminPW, nil -} - -func generatePassword(Len int) string { - 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() -} diff --git a/routes/user/user_test.go b/routes/user/user_test.go index 984f084..9309c87 100644 --- a/routes/user/user_test.go +++ b/routes/user/user_test.go @@ -75,7 +75,7 @@ func TestMain(m *testing.M) { func TestAuthenticate(t *testing.T) { database.DropTables() database.MigrateModels() - adminpw, err := database.DBAddAdminUser(configuration.GlobalConfig) + adminpw, err := database.AddAdminUser(configuration.GlobalConfig) assert.NoError(t, err) // try to authenticate with non JSON body @@ -172,7 +172,7 @@ func TestAuthenticateQueryToken(t *testing.T) { database.DropTables() database.MigrateModels() - adminpw, err := database.DBAddAdminUser(configuration.GlobalConfig) + adminpw, err := database.AddAdminUser(configuration.GlobalConfig) assert.NoError(t, err) // authenticate as admin @@ -193,7 +193,7 @@ func TestAddGetUser(t *testing.T) { database.DropTables() database.MigrateModels() - adminpw, err := database.DBAddAdminUser(configuration.GlobalConfig) + adminpw, err := database.AddAdminUser(configuration.GlobalConfig) assert.NoError(t, err) // authenticate as admin @@ -317,7 +317,7 @@ func TestUsersNotAllowedActions(t *testing.T) { database.DropTables() database.MigrateModels() - adminpw, err := database.DBAddAdminUser(configuration.GlobalConfig) + adminpw, err := database.AddAdminUser(configuration.GlobalConfig) assert.NoError(t, err) // authenticate as admin @@ -376,7 +376,7 @@ func TestGetAllUsers(t *testing.T) { database.DropTables() database.MigrateModels() - adminpw, err := database.DBAddAdminUser(configuration.GlobalConfig) + adminpw, err := database.AddAdminUser(configuration.GlobalConfig) assert.NoError(t, err) // authenticate as admin @@ -429,7 +429,7 @@ func TestModifyAddedUserAsUser(t *testing.T) { database.DropTables() database.MigrateModels() - adminpw, err := database.DBAddAdminUser(configuration.GlobalConfig) + adminpw, err := database.AddAdminUser(configuration.GlobalConfig) assert.NoError(t, err) // authenticate as admin @@ -584,7 +584,7 @@ func TestInvalidUserUpdate(t *testing.T) { database.DropTables() database.MigrateModels() - adminpw, err := database.DBAddAdminUser(configuration.GlobalConfig) + adminpw, err := database.AddAdminUser(configuration.GlobalConfig) assert.NoError(t, err) // authenticate as admin @@ -656,7 +656,7 @@ func TestModifyAddedUserAsAdmin(t *testing.T) { database.DropTables() database.MigrateModels() - adminpw, err := database.DBAddAdminUser(configuration.GlobalConfig) + adminpw, err := database.AddAdminUser(configuration.GlobalConfig) assert.NoError(t, err) // authenticate as admin @@ -773,7 +773,7 @@ func TestDeleteUser(t *testing.T) { database.DropTables() database.MigrateModels() - adminpw, err := database.DBAddAdminUser(configuration.GlobalConfig) + adminpw, err := database.AddAdminUser(configuration.GlobalConfig) assert.NoError(t, err) // authenticate as admin diff --git a/start.go b/start.go index b8088d2..980a32b 100644 --- a/start.go +++ b/start.go @@ -115,14 +115,14 @@ func main() { routes.RegisterEndpoints(r, api) // Start AMQP client - AMQPhost, _ := configuration.GlobalConfig.String("amqp.host") - AMQPuser, _ := configuration.GlobalConfig.String("amqp.user") - AMQPpass, _ := configuration.GlobalConfig.String("amqp.pass") + amqpHost, _ := configuration.GlobalConfig.String("amqp.host") + amqpUser, _ := configuration.GlobalConfig.String("amqp.user") + amqpPass, _ := configuration.GlobalConfig.String("amqp.pass") - if AMQPhost != "" { + if amqpHost != "" { // create amqp URL based on username, password and host - amqpurl := "amqp://" + AMQPuser + ":" + AMQPpass + "@" + AMQPhost - err = infrastructure_component.StartAMQP(amqpurl, api) + amqpURL := "amqp://" + amqpUser + ":" + amqpPass + "@" + amqpHost + err = infrastructure_component.StartAMQP(amqpURL, api) if err != nil { log.Fatal(err) } @@ -135,7 +135,7 @@ func main() { } // Make sure that at least one admin user exists in DB - _, err = database.DBAddAdminUser(configuration.GlobalConfig) + _, err = database.AddAdminUser(configuration.GlobalConfig) if err != nil { fmt.Println("error: adding admin user failed:", err.Error()) log.Fatal(err)