Commit 616a1c74 authored by Sonja Happ's avatar Sonja Happ
Browse files

WIP: adding test data via JSON file #44

parent d99b7691
......@@ -61,6 +61,7 @@ func InitConfig() error {
s3PathStyle = flag.Bool("s3-pathstyle", false, "Use path-style S3 API")
jwtSecret = flag.String("jwt-secret", "This should NOT be here!!@33$8&", "The JSON Web Token secret")
jwtExpiresAfter = flag.String("jwt-expires-after", "168h" /* 1 week */, "The time after which the JSON Web Token expires")
testDataPath = flag.String("test-data-path", "database/testdata.json", "The path to the test data json file (used in test mode)")
)
flag.Parse()
......@@ -85,6 +86,7 @@ func InitConfig() error {
"s3.region": *s3Region,
"jwt.secret": *jwtSecret,
"jwt.expires-after": *jwtExpiresAfter,
"test.datapath": *testDataPath,
}
if *s3NoSSL == true {
......@@ -122,6 +124,7 @@ func InitConfig() error {
"S3_PATHSTYLE": "s3.pathstyle",
"JWT_SECRET": "jwt.secret",
"JWT_EXPIRES_AFTER": "jwt.expires-after",
"TEST_DATA_PATH": "test.datapath",
}
defaults := config.NewStatic(static)
......
......@@ -23,8 +23,11 @@ package database
import (
"fmt"
"golang.org/x/crypto/bcrypt"
"log"
"math/rand"
"strings"
"time"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres"
......@@ -110,3 +113,58 @@ func MigrateModels() {
DBpool.AutoMigrate(&Widget{})
DBpool.AutoMigrate(&Result{})
}
// DBAddAdminUser adds a default admin user to the DB
func DBAddAdminUser(cfg *config.Config) (error, string) {
DBpool.AutoMigrate(User{})
// Check if admin user exists in DB
var users []User
err := DBpool.Where("Role = ?", "Admin").Find(&users).Error
adminPW := ""
if len(users) == 0 {
fmt.Println("No admin user found in DB, adding default admin user.")
name, err := cfg.String("admin.user")
if err != nil || name == "" {
name = "admin"
}
adminPW, err = cfg.String("admin.pass")
if err != nil || adminPW == "" {
adminPW = generatePassword(16)
fmt.Printf(" Generated admin password: %s\n", adminPW)
}
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: name, Password: string(pwEnc),
Role: "Admin", Mail: mail, Active: true}
// add admin user to DB
err = DBpool.Create(&user).Error
}
return err, adminPW
}
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()
}
{
"users": [
{
"username": "User_0",
"password": "xyz789",
"role": "Admin",
"mail": "User_0@example.com"
},
{
"username": "User_A",
"password": "abc123",
"role": "User",
"mail": "User_A@example.com"
},
{
"username": "User_B",
"password": "bcd234",
"role": "User",
"mail": "User_B@example.com"
},
{
"username": "User_C",
"password": "guestpw",
"role": "Guest",
"mail": "User_C@example.com"
}
],
"ics": [
{
"uuid": "7be0322d-354e-431e-84bd-ae4c9633138b",
"name": "ACS Demo Signals",
"type": "villas-node",
"category": "gateway",
"websocketurl": "https://villas.k8s.eonerc.rwth-aachen.de/ws/ws_sig",
"apiurl": "https://villas.k8s.eonerc.rwth-aachen.de/ws/api/v2",
"location": "K8S",
"description": "A signal generator for testing purposes",
"state": "idle",
"managedexternally": false,
"startparameterscheme": {
"param1": 42,
"param2": "testvalue"
}
},
{
"uuid": "4854af30-325f-44a5-ad59-b67b2597de68",
"name": "Test DPsim Simulator",
"type": "dpsim",
"category": "simulator",
"location": "acs lab",
"description": "DPsim simulator",
"state": "running",
"managedexternally": true,
"startparameterscheme": {
"param1": 55,
"param2": "testvalue2"
}
}
],
"scenarios": [
{
"name": "Scenario_A",
"startParameters": {
"param1": "a nice param",
"param2": "a not so nice param"
}
},
{
"name": "Scenario_B",
"startParameters": {
"param1": "another nice param",
"param2": "another not so nice param"
}
}
],
"configs": [
{
"name": "Example for Signal generator",
"startParameters": {
"param1": "nice param",
"param2": "not so nice"
},
"fileIDs" : []
},
{
"name": "Example for DPsim simulator",
"startParameters": {
"param1": "cool thing",
"param2": "who needs this"
},
"fileIDs" : []
}
],
"dashboards": [
{
"name": "Dashboard_A",
"grid": 15
},
{
"name": "Dashboard_B",
"grid": 10
}
],
"results": [
{
"description": "Test run 1"
},
{
"description": "Test run 2"
}
],
"widgets": [
{
"name": "MyLabel",
"type": "Label",
"width": 100,
"height": 50,
"minWidth": 40,
"minHeight": 80,
"x": 10,
"y": 10,
"z": 200,
"isLocked": false,
"signalIDs": [],
"customProperties": {
"textSize" : "20",
"fontColor" : "#4287f5",
"fontColor_opacity": 1
}
},
{
"name": "MySlider",
"type": "Slider",
"width": 400,
"height": 50,
"minWidth": 30,
"minHeight": 380,
"x": 70,
"y": 400,
"z": 0,
"isLocked": false,
"signalIDs": [],
"customProperties": {
"default_value" : 0,
"orientation" : 0,
"rangeMin" : 0,
"rangeMax": 200,
"rangeUseMinMax" : true,
"showUnit": true,
"continous_update": false,
"value": "",
"resizeLeftRightLock": false,
"resizeTopBottomLock": true,
"step": 0.1
}
},
{
"name": "MyBox",
"type": "Box",
"width": 200,
"height": 200,
"minWidth": 10,
"minHeight": 50,
"x": 300,
"y": 10,
"z": 0,
"isLocked": false,
"signalIDs": [],
"customProperties": {
"border_color" : "#4287f5",
"border_color_opacity": 1,
"background_color" : "#961520",
"background_color_opacity" : 1
}
},
{
"name": "MyButton",
"type": "Button",
"width": 100,
"height": 100,
"minWidth": 50,
"minHeight": 100,
"x": 10,
"y": 50,
"z": 0,
"isLocked": false,
"signalIDs": [],
"customProperties": {
"pressed": false,
"toggle" : false,
"on_value" : 1,
"off_value" : 0,
"background_color": "#961520",
"font_color": "#4287f5",
"border_color": "#4287f5",
"background_color_opacity": 1
}
},
{
"name": "MyLamp",
"type": "Lamp",
"width": 200,
"height": 20,
"minWidth": 10,
"minHeight": 50,
"x": 50,
"y": 300,
"z": 0,
"isLocked": false,
"signalIDs": [],
"customProperties": {
"on_color" : "#4287f5",
"off_color": "#961520",
"threshold" : 0.5,
"on_color_opacity": 1,
"off_color_opacity": 1
}
}
],
"signals": [
{
"name": "outSignal_A",
"direction": "out",
"unit": "V",
"index": 1
},
{
"name": "outSignal_B",
"direction": "out",
"unit": "V",
"index": 2
},
{
"name": "outSignal_C",
"direction": "out",
"unit": "---",
"index": 3
},
{
"name": "outSignal_D",
"direction": "out",
"unit": "---",
"index": 4
},
{
"name": "outSignal_E",
"direction": "out",
"unit": "---",
"index": 5
},
{
"name": "inSignal_A",
"direction": "in",
"unit": "---",
"index": 1
},
{
"name": "inSignal_B",
"direction": "in",
"unit": "---",
"index": 2
}
]
}
\ No newline at end of file
......@@ -24,20 +24,37 @@ package helper
import (
"encoding/json"
"fmt"
"math/rand"
"strings"
"time"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
"github.com/jinzhu/gorm/dialects/postgres"
"github.com/zpatrick/go-config"
"golang.org/x/crypto/bcrypt"
"io/ioutil"
"log"
"os"
)
// #######################################################################
// #################### Data used for testing ############################
// #######################################################################
type jsonUser struct {
Username string
Password string
Mail string
Role string
}
var GlobalTestData struct {
Users []jsonUser
ICs []database.InfrastructureComponent
Scenarios []database.Scenario
Results []database.Result
Configs []database.ComponentConfiguration
Dashboards []database.Dashboard
Widgets []database.Widget
Signals []database.Signal
}
// Credentials
var StrPassword0 = "xyz789"
var StrPasswordA = "abc123"
......@@ -46,13 +63,10 @@ var StrPasswordC = "guestpw"
// Hash passwords with bcrypt algorithm
var bcryptCost = 10
var pw0, _ = bcrypt.GenerateFromPassword([]byte(StrPassword0), bcryptCost)
var pwA, _ = bcrypt.GenerateFromPassword([]byte(StrPasswordA), bcryptCost)
var pwB, _ = bcrypt.GenerateFromPassword([]byte(StrPasswordB), bcryptCost)
var pwC, _ = bcrypt.GenerateFromPassword([]byte(StrPasswordC), bcryptCost)
var User0 = database.User{Username: "User_0", Password: string(pw0),
Role: "Admin", Mail: "User_0@example.com", Active: true}
var UserA = database.User{Username: "User_A", Password: string(pwA),
Role: "User", Mail: "User_A@example.com", Active: true}
var UserB = database.User{Username: "User_B", Password: string(pwB),
......@@ -216,35 +230,6 @@ var DashboardB = database.Dashboard{
Grid: 10,
}
// Files
var FileA = database.File{
Name: "File_A",
Type: "text/plain",
Size: 42,
Date: time.Now().String(),
}
var FileB = database.File{
Name: "File_B",
Type: "text/plain",
Size: 1234,
Date: time.Now().String(),
}
var FileC = database.File{
Name: "File_C",
Type: "text/plain",
Size: 32,
Date: time.Now().String(),
}
var FileD = database.File{
Name: "File_D",
Type: "text/plain",
Size: 5000,
Date: time.Now().String(),
}
// Widgets
var customPropertiesBox = json.RawMessage(`{"border_color" : "#4287f5", "border_color_opacity": 1, "background_color" : "#961520", "background_color_opacity" : 1}`)
var customPropertiesSlider = json.RawMessage(`{"default_value" : 0, "orientation" : 0, "rangeUseMinMax": false, "rangeMin" : 0, "rangeMax": 200, "rangeUseMinMax" : true, "showUnit": true, "continous_update": false, "value": "", "resizeLeftRightLock": false, "resizeTopBottomLock": true, "step": 0.1 }`)
......@@ -327,84 +312,63 @@ var WidgetE = database.Widget{
SignalIDs: []int64{},
}
func generatePassword(Len int) string {
rand.Seed(time.Now().UnixNano())
chars := []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
"abcdefghijklmnopqrstuvwxyz" +
"0123456789")
func ReadTestDataFromJson(path string) error {
var b strings.Builder
for i := 0; i < Len; i++ {
b.WriteRune(chars[rand.Intn(len(chars))])
jsonFile, err := os.Open(path)
if err != nil {
return fmt.Errorf("error opening json file: %v", err)
}
log.Println("Successfully opened json data file", path)
return b.String()
}
// DBAddAdminUser adds a default admin user to the DB
func DBAddAdminUser(cfg *config.Config) error {
database.DBpool.AutoMigrate(&database.User{})
// Check if admin user exists in DB
var users []database.User
err := database.DBpool.Where("Role = ?", "Admin").Find(&users).Error
defer jsonFile.Close()
if len(users) == 0 {
fmt.Println("No admin user found in DB, adding default admin user.")
byteValue, _ := ioutil.ReadAll(jsonFile)
mode, err := cfg.String("mode")
err = json.Unmarshal(byteValue, &GlobalTestData)
if err != nil {
return fmt.Errorf("error unmarshalling json: %v", err)
}
name, err := cfg.String("admin.user")
if (err != nil || name == "") && mode != "test" {
name = "admin"
} else if mode == "test" {
name = User0.Username
}
log.Println(len(GlobalTestData.Users))
pw, err := cfg.String("admin.pass")
if (err != nil || pw == "") && mode != "test" {
pw = generatePassword(16)
fmt.Printf(" Generated admin password: %s\n", pw)
} else if mode == "test" {
pw = StrPassword0
}
mail, err := cfg.String("admin.mail")
if (err == nil || mail == "") && mode != "test" {
mail = "admin@example.com"
} else if mode == "test" {
mail = User0.Mail
}
pwEnc, _ := bcrypt.GenerateFromPassword([]byte(pw), bcryptCost)
return nil
}
// create a copy of global test data
user := database.User{Username: name, Password: string(pwEnc),
Role: "Admin", Mail: mail, Active: true}
// add default admin user, normal users and a guest to the DB
func AddTestUsers() error {
// add admin user to DB
err = database.DBpool.Create(&user).Error
err := ReadTestDataFromJson("../../testdata/testdata.json")
if err != nil {
return err
}
return err
}
//create a copy of global test data
if len(GlobalTestData.Users) == 0 {
return fmt.Errorf("no users in test data")
}
// add default admin user, normal users and a guest to the DB
func DBAddAdminAndUserAndGuest() error {
database.DBpool.AutoMigrate(&database.User{})
err, _ = database.DBAddAdminUser(configuration.GlobalConfig)
if err != nil {
return err
}
//create a copy of global test data
user0 := User0
userA := UserA
userB := UserB
userC := UserC
// add admin user to DB
err := database.DBpool.Create(&user0).Error
// add normal users to DB
err = database.DBpool.Create(&userA).Error
err = database.DBpool.Create(&userB).Error
// add guest user to DB
err = database.DBpool.Create(&userC).Error
return err
for _, user := range GlobalTestData.Users {
if user.Role != "Admin" {
// add users to DB that are not admin users
var newUser database.User
newUser.Username = user.Username
newUser.Role = user.Role
newUser.Mail = user.Mail
pwEnc, _ := bcrypt.GenerateFromPassword([]byte(user.Password), 10)
newUser.Password = string(pwEnc)
err = database.DBpool.Create(&newUser).Error
if err != nil {
return err
}
}
}
return nil
}
......@@ -41,13 +41,13 @@ type KeyModels map[string]interface{}
// #######################################################################
type Credentials struct {
Username string
Password string
Username string `json:"username,required"`
Password string `json:"password,required"`
}
var AdminCredentials = Credentials{
Username: "User_0",
Password: StrPassword0,
Username: "admin",
Password: "xyz789",
}
var UserACredentials = Credentials{
......
......@@ -172,7 +172,7 @@ func TestMain(m *testing.M) {
func TestAddConfig(t *testing.T) {
database.DropTables()
database.MigrateModels()
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
assert.NoError(t, helper.AddTestUsers())
// prepare the content of the DB for testing
// by adding a scenario and a IC to the DB
......@@ -268,7 +268,7 @@ func TestUpdateConfig(t *testing.T) {