- revise naming of some common functions

- improve returning of error codes by using common functions
- use a separate file for authentication endpoint to improve clarity of code
This commit is contained in:
Sonja Happ 2019-09-09 15:30:17 +02:00
parent 71ab20bbef
commit 2ffda7cad8
30 changed files with 472 additions and 802 deletions

View file

@ -3,43 +3,48 @@ package common
import ( import (
"flag" "flag"
"fmt" "fmt"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm" "github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres" _ "github.com/jinzhu/gorm/dialects/postgres"
"log" "log"
"net/http"
) )
var DB_HOST string var DB_HOST string // host of the database system
var DB_NAME string var DB_NAME string // name of the production database
var DB_DUMMY string var DB_TEST string // name of the test database
var DB_SSLMODE string var DB_SSLMODE string // set to enable if database uses SSL
var WITH_AMQP bool var WITH_AMQP bool // set to true if backend shall be used with AMQP client
var DBpool *gorm.DB var DBpool *gorm.DB // database used by backend
// Initialize input command line flags // Initialize input command line flags
func init() { func init() {
flag.StringVar(&DB_HOST, "dbhost", "/var/run/postgresql", "Host of the PostgreSQL database (default is /var/run/postgresql for localhost DB on Ubuntu systems)") flag.StringVar(&DB_HOST, "dbhost", "/var/run/postgresql", "Host of the PostgreSQL database (default is /var/run/postgresql for localhost DB on Ubuntu systems)")
flag.StringVar(&DB_NAME, "dbname", "villasdb", "Name of the database to use (default is villasdb)") flag.StringVar(&DB_NAME, "dbname", "villasdb", "Name of the database to use (default is villasdb)")
flag.StringVar(&DB_DUMMY, "dbdummy", "testvillasdb", "Name of the test database to use (default is testvillasdb)") flag.StringVar(&DB_TEST, "dbdummy", "testvillasdb", "Name of the test database to use (default is testvillasdb)")
flag.StringVar(&DB_SSLMODE, "dbsslmode", "disable", "SSL mode of DB (default is disable)") // TODO: change default for production flag.StringVar(&DB_SSLMODE, "dbsslmode", "disable", "SSL mode of DB (default is disable)") // TODO: change default for production
flag.BoolVar(&WITH_AMQP, "amqp", false, "If AMQP client for simulators shall be enabled, set this option to true (default is false)") flag.BoolVar(&WITH_AMQP, "amqp", false, "If AMQP client for simulators shall be enabled, set this option to true (default is false)")
flag.Parse() flag.Parse()
fmt.Println("DB_HOST has value ", DB_HOST) fmt.Println("DB_HOST has value ", DB_HOST)
fmt.Println("DB_NAME has value ", DB_NAME) fmt.Println("DB_NAME has value ", DB_NAME)
fmt.Println("DB_DUMMY has value ", DB_DUMMY) fmt.Println("DB_TEST has value ", DB_TEST)
fmt.Println("DB_SSLMODE has value ", DB_SSLMODE) fmt.Println("DB_SSLMODE has value ", DB_SSLMODE)
fmt.Println("WITH_AMQP has value ", WITH_AMQP) fmt.Println("WITH_AMQP has value ", WITH_AMQP)
} }
// Initialize connection to the database // Initialize connection to the database
func InitDB() *gorm.DB { func InitDB(dbname string) *gorm.DB {
dbinfo := fmt.Sprintf("host=%s sslmode=%s dbname=%s", dbinfo := fmt.Sprintf("host=%s sslmode=%s dbname=%s",
DB_HOST, DB_SSLMODE, DB_NAME) DB_HOST, DB_SSLMODE, dbname)
db, err := gorm.Open("postgres", dbinfo) db, err := gorm.Open("postgres", dbinfo)
checkErr(err) checkErr(err)
DBpool = db DBpool = db
if dbname == DB_TEST {
// if we are using the test DB
// drop tables from previous tests
DropTables(db)
}
return db return db
} }
@ -48,11 +53,6 @@ func GetDB() *gorm.DB {
return DBpool return DBpool
} }
// Verify that the database connection is alive
func VerifyConnection(db *gorm.DB) error {
return db.DB().Ping()
}
// Drop all the tables of the database // Drop all the tables of the database
// TODO: Remove that function from the codebase and substitute the body // TODO: Remove that function from the codebase and substitute the body
// to the Dummy*() where it is called // to the Dummy*() where it is called
@ -65,6 +65,7 @@ func DropTables(db *gorm.DB) {
db.DropTableIfExists(&User{}) db.DropTableIfExists(&User{})
db.DropTableIfExists(&Dashboard{}) db.DropTableIfExists(&Dashboard{})
db.DropTableIfExists(&Widget{}) db.DropTableIfExists(&Widget{})
// The following statement deletes the many to many relationship between users and scenarios
db.DropTableIfExists("user_scenarios") db.DropTableIfExists("user_scenarios")
} }
@ -80,133 +81,6 @@ func MigrateModels(db *gorm.DB) {
db.AutoMigrate(&Widget{}) db.AutoMigrate(&Widget{})
} }
// Start a dummy database for testing
func DummyInitDB() *gorm.DB {
dbinfo := fmt.Sprintf("host=%s sslmode=%s dbname=%s",
DB_HOST, DB_SSLMODE, DB_DUMMY)
test_db, err := gorm.Open("postgres", dbinfo)
checkErr(err)
DBpool = test_db
// drop tables from previous tests
DropTables(test_db)
return test_db
}
func DummyAddOnlyUserTableWithAdminDB(db *gorm.DB) {
db.AutoMigrate(&User{})
//create a copy of global test data
user0 := User0
// add admin user to DB
checkErr(db.Create(&user0).Error)
}
func DummyAddOnlyUserTableWithAdminAndUsersDB(db *gorm.DB) {
db.AutoMigrate(&User{})
//create a copy of global test data
user0 := User0
userA := UserA
userB := UserB
// add admin user to DB
checkErr(db.Create(&user0).Error)
// add normal users to DB
checkErr(db.Create(&userA).Error)
checkErr(db.Create(&userB).Error)
}
// Migrates models and populates them with data
func DummyPopulateDB(test_db *gorm.DB) {
MigrateModels(test_db)
// Create entries of each model (data defined in testdata.go)
// Users
checkErr(test_db.Create(&User0).Error) // Admin
checkErr(test_db.Create(&UserA).Error) // Normal User
checkErr(test_db.Create(&UserB).Error) // Normal User
// Simulators
checkErr(test_db.Create(&SimulatorA).Error)
checkErr(test_db.Create(&SimulatorB).Error)
// Scenarios
checkErr(test_db.Create(&ScenarioA).Error)
checkErr(test_db.Create(&ScenarioB).Error)
// Signals
checkErr(test_db.Create(&OutSignalA).Error)
checkErr(test_db.Create(&OutSignalB).Error)
checkErr(test_db.Create(&InSignalA).Error)
checkErr(test_db.Create(&InSignalB).Error)
// Simulation Models
checkErr(test_db.Create(&SimulationModelA).Error)
checkErr(test_db.Create(&SimulationModelB).Error)
// Dashboards
checkErr(test_db.Create(&DashboardA).Error)
checkErr(test_db.Create(&DashboardB).Error)
// Files
checkErr(test_db.Create(&FileA).Error)
checkErr(test_db.Create(&FileB).Error)
checkErr(test_db.Create(&FileC).Error)
checkErr(test_db.Create(&FileD).Error)
// Widgets
checkErr(test_db.Create(&WidgetA).Error)
checkErr(test_db.Create(&WidgetB).Error)
// Associations between models
// For `belongs to` use the model with id=1
// For `has many` use the models with id=1 and id=2
// User HM Scenarios, Scenario HM Users (Many-to-Many)
checkErr(test_db.Model(&ScenarioA).Association("Users").Append(&UserA).Error)
checkErr(test_db.Model(&ScenarioA).Association("Users").Append(&UserB).Error)
checkErr(test_db.Model(&ScenarioB).Association("Users").Append(&UserA).Error)
checkErr(test_db.Model(&ScenarioB).Association("Users").Append(&UserB).Error)
// Scenario HM SimulationModels
checkErr(test_db.Model(&ScenarioA).Association("SimulationModels").Append(&SimulationModelA).Error)
checkErr(test_db.Model(&ScenarioA).Association("SimulationModels").Append(&SimulationModelB).Error)
// Scenario HM Dashboards
checkErr(test_db.Model(&ScenarioA).Association("Dashboards").Append(&DashboardA).Error)
checkErr(test_db.Model(&ScenarioA).Association("Dashboards").Append(&DashboardB).Error)
// Dashboard HM Widget
checkErr(test_db.Model(&DashboardA).Association("Widgets").Append(&WidgetA).Error)
checkErr(test_db.Model(&DashboardA).Association("Widgets").Append(&WidgetB).Error)
// SimulationModel HM Signals
checkErr(test_db.Model(&SimulationModelA).Association("InputMapping").Append(&InSignalA).Error)
checkErr(test_db.Model(&SimulationModelA).Association("InputMapping").Append(&InSignalB).Error)
checkErr(test_db.Model(&SimulationModelA).Association("OutputMapping").Append(&OutSignalA).Error)
checkErr(test_db.Model(&SimulationModelA).Association("OutputMapping").Append(&OutSignalB).Error)
// SimulationModel HM Files
checkErr(test_db.Model(&SimulationModelA).Association("Files").Append(&FileC).Error)
checkErr(test_db.Model(&SimulationModelA).Association("Files").Append(&FileD).Error)
// Simulator HM SimulationModels
checkErr(test_db.Model(&SimulatorA).Association("SimulationModels").Append(&SimulationModelA).Error)
checkErr(test_db.Model(&SimulatorA).Association("SimulationModels").Append(&SimulationModelB).Error)
// Widget HM Files
checkErr(test_db.Model(&WidgetA).Association("Files").Append(&FileA).Error)
checkErr(test_db.Model(&WidgetA).Association("Files").Append(&FileB).Error)
}
// Erase tables and glose the testdb
func DummyCloseDB(test_db *gorm.DB) {
test_db.Close()
}
// Quick error check // Quick error check
// NOTE: maybe this is not a good idea // NOTE: maybe this is not a good idea
func checkErr(err error) { func checkErr(err error) {
@ -214,23 +88,3 @@ func checkErr(err error) {
log.Fatal(err) log.Fatal(err)
} }
} }
func DBError(c *gin.Context, err error) bool {
if err != nil {
if err == gorm.ErrRecordNotFound {
errormsg := "Record not Found in DB: " + err.Error()
c.JSON(http.StatusNotFound, gin.H{
"success": false,
"message": errormsg,
})
} else {
errormsg := "Error on DB Query or transaction: " + err.Error()
c.JSON(http.StatusInternalServerError, gin.H{
"success": false,
"message": errormsg,
})
}
return true // Error
}
return false // No error
}

View file

@ -12,7 +12,7 @@ import (
var db *gorm.DB var db *gorm.DB
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
db = DummyInitDB() db = InitDB(DB_TEST)
// Verify that you can connect to the database // Verify that you can connect to the database
err := db.DB().Ping() err := db.DB().Ping()

69
common/http_errors.go Normal file
View file

@ -0,0 +1,69 @@
package common
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
"net/http"
)
func DBError(c *gin.Context, err error) bool {
if err != nil {
if err == gorm.ErrRecordNotFound {
NotFoundError(c, "Record not Found in DB: "+err.Error())
} else {
InternalServerError(c, "Error on DB Query or transaction: "+err.Error())
}
return true // Error
}
return false // No error
}
func BadRequestError(c *gin.Context, err string) {
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
}
func UnprocessableEntityError(c *gin.Context, err string) {
c.JSON(http.StatusUnprocessableEntity, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
}
func InternalServerError(c *gin.Context, err string) {
c.JSON(http.StatusInternalServerError, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
}
func UnauthorizedError(c *gin.Context, err string) {
c.JSON(http.StatusUnauthorized, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
}
func UnauthorizedAbort(c *gin.Context, err string) {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
"succes": false,
"message": fmt.Sprintf("%v", err),
})
}
func NotFoundError(c *gin.Context, err string) {
c.JSON(http.StatusNotFound, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
}
func ForbiddenError(c *gin.Context, err string) {
c.JSON(http.StatusForbidden, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
}

View file

@ -5,6 +5,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
"github.com/jinzhu/gorm/dialects/postgres" "github.com/jinzhu/gorm/dialects/postgres"
"github.com/nsf/jsondiff" "github.com/nsf/jsondiff"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
@ -404,3 +405,111 @@ func AuthenticateForTest(router *gin.Engine, url string,
// Return the token and nil error // Return the token and nil error
return token, nil return token, nil
} }
func DBAddAdminUser(db *gorm.DB) {
db.AutoMigrate(&User{})
//create a copy of global test data
user0 := User0
// add admin user to DB
checkErr(db.Create(&user0).Error)
}
func DBAddAdminAndUser(db *gorm.DB) {
db.AutoMigrate(&User{})
//create a copy of global test data
user0 := User0
userA := UserA
userB := UserB
// add admin user to DB
checkErr(db.Create(&user0).Error)
// add normal users to DB
checkErr(db.Create(&userA).Error)
checkErr(db.Create(&userB).Error)
}
// Migrates models and populates them with data
func AddTestData(test_db *gorm.DB) {
MigrateModels(test_db)
// Create entries of each model (data defined in testdata.go)
// Users
checkErr(test_db.Create(&User0).Error) // Admin
checkErr(test_db.Create(&UserA).Error) // Normal User
checkErr(test_db.Create(&UserB).Error) // Normal User
// Simulators
checkErr(test_db.Create(&SimulatorA).Error)
checkErr(test_db.Create(&SimulatorB).Error)
// Scenarios
checkErr(test_db.Create(&ScenarioA).Error)
checkErr(test_db.Create(&ScenarioB).Error)
// Signals
checkErr(test_db.Create(&OutSignalA).Error)
checkErr(test_db.Create(&OutSignalB).Error)
checkErr(test_db.Create(&InSignalA).Error)
checkErr(test_db.Create(&InSignalB).Error)
// Simulation Models
checkErr(test_db.Create(&SimulationModelA).Error)
checkErr(test_db.Create(&SimulationModelB).Error)
// Dashboards
checkErr(test_db.Create(&DashboardA).Error)
checkErr(test_db.Create(&DashboardB).Error)
// Files
checkErr(test_db.Create(&FileA).Error)
checkErr(test_db.Create(&FileB).Error)
checkErr(test_db.Create(&FileC).Error)
checkErr(test_db.Create(&FileD).Error)
// Widgets
checkErr(test_db.Create(&WidgetA).Error)
checkErr(test_db.Create(&WidgetB).Error)
// Associations between models
// For `belongs to` use the model with id=1
// For `has many` use the models with id=1 and id=2
// User HM Scenarios, Scenario HM Users (Many-to-Many)
checkErr(test_db.Model(&ScenarioA).Association("Users").Append(&UserA).Error)
checkErr(test_db.Model(&ScenarioA).Association("Users").Append(&UserB).Error)
checkErr(test_db.Model(&ScenarioB).Association("Users").Append(&UserA).Error)
checkErr(test_db.Model(&ScenarioB).Association("Users").Append(&UserB).Error)
// Scenario HM SimulationModels
checkErr(test_db.Model(&ScenarioA).Association("SimulationModels").Append(&SimulationModelA).Error)
checkErr(test_db.Model(&ScenarioA).Association("SimulationModels").Append(&SimulationModelB).Error)
// Scenario HM Dashboards
checkErr(test_db.Model(&ScenarioA).Association("Dashboards").Append(&DashboardA).Error)
checkErr(test_db.Model(&ScenarioA).Association("Dashboards").Append(&DashboardB).Error)
// Dashboard HM Widget
checkErr(test_db.Model(&DashboardA).Association("Widgets").Append(&WidgetA).Error)
checkErr(test_db.Model(&DashboardA).Association("Widgets").Append(&WidgetB).Error)
// SimulationModel HM Signals
checkErr(test_db.Model(&SimulationModelA).Association("InputMapping").Append(&InSignalA).Error)
checkErr(test_db.Model(&SimulationModelA).Association("InputMapping").Append(&InSignalB).Error)
checkErr(test_db.Model(&SimulationModelA).Association("OutputMapping").Append(&OutSignalA).Error)
checkErr(test_db.Model(&SimulationModelA).Association("OutputMapping").Append(&OutSignalB).Error)
// SimulationModel HM Files
checkErr(test_db.Model(&SimulationModelA).Association("Files").Append(&FileC).Error)
checkErr(test_db.Model(&SimulationModelA).Association("Files").Append(&FileD).Error)
// Simulator HM SimulationModels
checkErr(test_db.Model(&SimulatorA).Association("SimulationModels").Append(&SimulationModelA).Error)
checkErr(test_db.Model(&SimulatorA).Association("SimulationModels").Append(&SimulationModelB).Error)
// Widget HM Files
checkErr(test_db.Model(&WidgetA).Association("Files").Append(&FileA).Error)
checkErr(test_db.Model(&WidgetA).Association("Files").Append(&FileB).Error)
}

View file

@ -1,7 +1,6 @@
package dashboard package dashboard
import ( import (
"fmt"
"net/http" "net/http"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -44,9 +43,7 @@ func getDashboards(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"dashboards": dab})
"dashboards": dab,
})
} }
// addDashboard godoc // addDashboard godoc
@ -67,19 +64,13 @@ func addDashboard(c *gin.Context) {
// bind request to JSON // bind request to JSON
var req addDashboardRequest var req addDashboardRequest
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
// Validate the request // Validate the request
if err := req.validate(); err != nil { if err := req.validate(); err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
@ -99,10 +90,7 @@ func addDashboard(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"dashboard": newDashboard.Dashboard})
"dashboard": newDashboard.Dashboard,
})
} }
// updateDashboard godoc // updateDashboard godoc
@ -128,28 +116,19 @@ func updateDashboard(c *gin.Context) {
var req updateDashboardRequest var req updateDashboardRequest
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
// Validate the request // Validate the request
if err := req.validate(); err != nil { if err := req.validate(); err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
// Create the updatedDashboard from oldDashboard // Create the updatedDashboard from oldDashboard
updatedDashboard, err := req.updatedDashboard(oldDashboard) updatedDashboard, err := req.updatedDashboard(oldDashboard)
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
@ -160,10 +139,7 @@ func updateDashboard(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"dashboard": updatedDashboard.Dashboard})
"dashboard": updatedDashboard.Dashboard,
})
} }
// getDashboard godoc // getDashboard godoc
@ -185,9 +161,7 @@ func getDashboard(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"dashboard": dab.Dashboard})
"dashboard": dab.Dashboard,
})
} }
// deleteDashboard godoc // deleteDashboard godoc
@ -213,7 +187,5 @@ func deleteDashboard(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"dashboard": dab.Dashboard})
"dashboard": dab.Dashboard,
})
} }

View file

@ -3,7 +3,6 @@ package dashboard
import ( import (
"fmt" "fmt"
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/scenario" "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/scenario"
"net/http"
"strconv" "strconv"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -17,10 +16,7 @@ func CheckPermissions(c *gin.Context, operation common.CRUD, dabIDSource string,
err := common.ValidateRole(c, common.ModelDashboard, operation) err := common.ValidateRole(c, common.ModelDashboard, operation)
if err != nil { if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, fmt.Sprintf("Access denied (role validation failed): %v", err.Error()))
"success": false,
"message": fmt.Sprintf("Access denied (role validation failed): %v", err),
})
return false, dab return false, dab
} }
@ -28,19 +24,13 @@ func CheckPermissions(c *gin.Context, operation common.CRUD, dabIDSource string,
if dabIDSource == "path" { if dabIDSource == "path" {
dabID, err = strconv.Atoi(c.Param("dashboardID")) dabID, err = strconv.Atoi(c.Param("dashboardID"))
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, fmt.Sprintf("No or incorrect format of dashboardID path parameter"))
"success": false,
"message": fmt.Sprintf("Bad request. No or incorrect format of dashboardID path parameter"),
})
return false, dab return false, dab
} }
} else if dabIDSource == "query" { } else if dabIDSource == "query" {
dabID, err = strconv.Atoi(c.Request.URL.Query().Get("dashboardID")) dabID, err = strconv.Atoi(c.Request.URL.Query().Get("dashboardID"))
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, fmt.Sprintf("No or incorrect format of dashboardID query parameter"))
"success": false,
"message": fmt.Sprintf("Bad request. No or incorrect format of dashboardID query parameter"),
})
return false, dab return false, dab
} }
} else if dabIDSource == "body" { } else if dabIDSource == "body" {

View file

@ -47,7 +47,7 @@ func addScenario(token string) (scenarioID uint) {
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
db = common.DummyInitDB() db = common.InitDB(common.DB_TEST)
defer db.Close() defer db.Close()
router = gin.Default() router = gin.Default()
@ -66,7 +66,7 @@ func TestMain(m *testing.M) {
func TestAddDashboard(t *testing.T) { func TestAddDashboard(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as normal user // authenticate as normal user
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -120,7 +120,7 @@ func TestAddDashboard(t *testing.T) {
func TestUpdateDashboard(t *testing.T) { func TestUpdateDashboard(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as normal user // authenticate as normal user
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -179,7 +179,7 @@ func TestUpdateDashboard(t *testing.T) {
func TestDeleteDashboard(t *testing.T) { func TestDeleteDashboard(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as normal user // authenticate as normal user
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -231,7 +231,7 @@ func TestDeleteDashboard(t *testing.T) {
func TestGetAllDashboardsOfScenario(t *testing.T) { func TestGetAllDashboardsOfScenario(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as normal user // authenticate as normal user
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,

View file

@ -36,19 +36,13 @@ func getFiles(c *gin.Context) {
objectType := c.Request.URL.Query().Get("objectType") objectType := c.Request.URL.Query().Get("objectType")
if objectType != "model" && objectType != "widget" { if objectType != "model" && objectType != "widget" {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, fmt.Sprintf("Object type not supported for files: %s", objectType))
"success": false,
"message": fmt.Sprintf("Bad request. Object type not supported for files: %s", objectType),
})
return return
} }
objectID_s := c.Request.URL.Query().Get("objectID") objectID_s := c.Request.URL.Query().Get("objectID")
objectID, err := strconv.Atoi(objectID_s) objectID, err := strconv.Atoi(objectID_s)
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, fmt.Sprintf("Error on ID conversion: %s", err.Error()))
"success": false,
"message": fmt.Sprintf("Bad request. Error on ID conversion: %s", err.Error()),
})
return return
} }
@ -84,10 +78,7 @@ func getFiles(c *gin.Context) {
} }
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"files": files})
"files": files,
})
} }
// addFile godoc // addFile godoc
@ -114,19 +105,13 @@ func addFile(c *gin.Context) {
objectType := c.Request.URL.Query().Get("objectType") objectType := c.Request.URL.Query().Get("objectType")
if objectType != "model" && objectType != "widget" { if objectType != "model" && objectType != "widget" {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, fmt.Sprintf("Object type not supported for files: %s", objectType))
"success": false,
"message": fmt.Sprintf("Bad request. Object type not supported for files: %s", objectType),
})
return return
} }
objectID_s := c.Request.URL.Query().Get("objectID") objectID_s := c.Request.URL.Query().Get("objectID")
objectID, err := strconv.Atoi(objectID_s) objectID, err := strconv.Atoi(objectID_s)
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, fmt.Sprintf("Error on ID conversion: %s", err.Error()))
"success": false,
"message": fmt.Sprintf("Bad request. Error on ID conversion: %s", err.Error()),
})
return return
} }
@ -147,10 +132,7 @@ func addFile(c *gin.Context) {
// Extract file from POST request form // Extract file from POST request form
file_header, err := c.FormFile("file") file_header, err := c.FormFile("file")
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, fmt.Sprintf("Get form error: %s", err.Error()))
"success": false,
"message": fmt.Sprintf("Bad request. Get form error: %s", err.Error()),
})
return return
} }
@ -161,9 +143,7 @@ func addFile(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"file": newFile.File})
"file": newFile.File,
})
} }
// getFile godoc // getFile godoc
@ -197,10 +177,7 @@ func getFile(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"file": f.File})
"file": f.File,
})
} }
// updateFile godoc // updateFile godoc
@ -233,19 +210,13 @@ func updateFile(c *gin.Context) {
// Extract file from PUT request form // Extract file from PUT request form
err := c.Request.ParseForm() err := c.Request.ParseForm()
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, fmt.Sprintf("Get form error: %s", err.Error()))
"success": false,
"message": fmt.Sprintf("Bad request. Get form error: %s", err.Error()),
})
return return
} }
file_header, err := c.FormFile("file") file_header, err := c.FormFile("file")
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, fmt.Sprintf("Get form error: %s", err.Error()))
"success": false,
"error": fmt.Sprintf("Bad request. Get form error: %s", err.Error()),
})
return return
} }
@ -255,9 +226,7 @@ func updateFile(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"file": f.File})
"file": f.File,
})
} }
// deleteFile godoc // deleteFile godoc
@ -286,7 +255,5 @@ func deleteFile(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"file": f.File})
"file": f.File,
})
} }

View file

@ -6,7 +6,6 @@ import (
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulationmodel" "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulationmodel"
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/widget" "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/widget"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"net/http"
"strconv" "strconv"
) )
@ -16,19 +15,13 @@ func checkPermissions(c *gin.Context, operation common.CRUD) (bool, File) {
err := common.ValidateRole(c, common.ModelFile, operation) err := common.ValidateRole(c, common.ModelFile, operation)
if err != nil { if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, fmt.Sprintf("Access denied (role validation failed): %v", err.Error()))
"success": false,
"message": fmt.Sprintf("Access denied (role validation failed): %v", err),
})
return false, f return false, f
} }
fileID, err := strconv.Atoi(c.Param("fileID")) fileID, err := strconv.Atoi(c.Param("fileID"))
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, fmt.Sprintf("No or incorrect format of fileID path parameter"))
"success": false,
"error": fmt.Sprintf("Bad request. No or incorrect format of fileID path parameter"),
})
return false, f return false, f
} }

View file

@ -99,7 +99,7 @@ func addScenarioAndSimulatorAndSimulationModel() (scenarioID uint, simulatorID u
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
db = common.DummyInitDB() db = common.InitDB(common.DB_TEST)
defer db.Close() defer db.Close()
router = gin.Default() router = gin.Default()
@ -124,7 +124,7 @@ func TestMain(m *testing.M) {
func TestAddFile(t *testing.T) { func TestAddFile(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// prepare the content of the DB for testing // prepare the content of the DB for testing
// by adding a scenario and a simulator to the DB // by adding a scenario and a simulator to the DB
@ -187,7 +187,7 @@ func TestUpdateFile(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// prepare the content of the DB for testing // prepare the content of the DB for testing
// by adding a scenario and a simulator to the DB // by adding a scenario and a simulator to the DB
@ -288,7 +288,7 @@ func TestUpdateFile(t *testing.T) {
func TestDeleteFile(t *testing.T) { func TestDeleteFile(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// prepare the content of the DB for testing // prepare the content of the DB for testing
// by adding a scenario and a simulator to the DB // by adding a scenario and a simulator to the DB
@ -362,7 +362,7 @@ func TestGetAllFilesOfSimulationModel(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// prepare the content of the DB for testing // prepare the content of the DB for testing
// by adding a scenario and a simulator to the DB // by adding a scenario and a simulator to the DB

View file

@ -1,7 +1,6 @@
package scenario package scenario
import ( import (
"fmt"
"net/http" "net/http"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -64,9 +63,7 @@ func getScenarios(c *gin.Context) {
} }
} }
// TODO return list of simulationModelIDs, dashboardIDs and userIDs per scenario // TODO return list of simulationModelIDs, dashboardIDs and userIDs per scenario
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"scenarios": scenarios})
"scenarios": scenarios,
})
} }
// addScenario godoc // addScenario godoc
@ -99,19 +96,13 @@ func addScenario(c *gin.Context) {
var req addScenarioRequest var req addScenarioRequest
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
// Validate the request // Validate the request
if err = req.validate(); err != nil { if err = req.validate(); err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
@ -132,9 +123,7 @@ func addScenario(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"scenario": newScenario.Scenario})
"scenario": newScenario.Scenario,
})
} }
// updateScenario godoc // updateScenario godoc
@ -161,29 +150,20 @@ func updateScenario(c *gin.Context) {
// Bind the (context) with the updateScenarioRequest struct // Bind the (context) with the updateScenarioRequest struct
var req updateScenarioRequest var req updateScenarioRequest
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
// Validate the request based on struct updateScenarioRequest json tags // Validate the request based on struct updateScenarioRequest json tags
if err := req.validate(); err != nil { if err := req.validate(); err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
// Create the updatedScenario from oldScenario // Create the updatedScenario from oldScenario
updatedScenario, err := req.updatedScenario(oldScenario) updatedScenario, err := req.updatedScenario(oldScenario)
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
@ -194,9 +174,7 @@ func updateScenario(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"scenario": updatedScenario.Scenario})
"scenario": updatedScenario.Scenario,
})
} }
// getScenario godoc // getScenario godoc
@ -218,9 +196,7 @@ func getScenario(c *gin.Context) {
} }
// TODO return list of simulationModelIDs, dashboardIDs and userIDs per scenario // TODO return list of simulationModelIDs, dashboardIDs and userIDs per scenario
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"scenario": so.Scenario})
"scenario": so.Scenario,
})
} }
// deleteScenario godoc // deleteScenario godoc
@ -247,9 +223,7 @@ func deleteScenario(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"scenario": so.Scenario})
"scenario": so.Scenario,
})
} }
// getUsersOfScenario godoc // getUsersOfScenario godoc
@ -311,9 +285,7 @@ func addUserToScenario(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"user": u.User})
"user": u.User,
})
} }
// deleteUserFromScenario godoc // deleteUserFromScenario godoc
@ -348,7 +320,5 @@ func deleteUserFromScenario(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"user": u.User})
"user": u.User,
})
} }

View file

@ -2,7 +2,6 @@ package scenario
import ( import (
"fmt" "fmt"
"net/http"
"strconv" "strconv"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -16,10 +15,7 @@ func CheckPermissions(c *gin.Context, operation common.CRUD, screnarioIDSource s
err := common.ValidateRole(c, common.ModelScenario, operation) err := common.ValidateRole(c, common.ModelScenario, operation)
if err != nil { if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, fmt.Sprintf("Access denied (role validation failed): %v", err))
"success": false,
"message": fmt.Sprintf("Access denied (role validation failed): %v", err),
})
return false, so return false, so
} }
@ -31,29 +27,20 @@ func CheckPermissions(c *gin.Context, operation common.CRUD, screnarioIDSource s
if screnarioIDSource == "path" { if screnarioIDSource == "path" {
scenarioID, err = strconv.Atoi(c.Param("scenarioID")) scenarioID, err = strconv.Atoi(c.Param("scenarioID"))
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, fmt.Sprintf("No or incorrect format of scenarioID path parameter"))
"success": false,
"message": fmt.Sprintf("Bad request. No or incorrect format of scenarioID path parameter"),
})
return false, so return false, so
} }
} else if screnarioIDSource == "query" { } else if screnarioIDSource == "query" {
scenarioID, err = strconv.Atoi(c.Request.URL.Query().Get("scenarioID")) scenarioID, err = strconv.Atoi(c.Request.URL.Query().Get("scenarioID"))
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, fmt.Sprintf("No or incorrect format of scenarioID query parameter"))
"success": false,
"message": fmt.Sprintf("Bad request. No or incorrect format of scenarioID query parameter"),
})
return false, so return false, so
} }
} else if screnarioIDSource == "body" { } else if screnarioIDSource == "body" {
scenarioID = screnarioIDBody scenarioID = screnarioIDBody
} else { } else {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, fmt.Sprintf("The following source of scenario ID is not valid: %s", screnarioIDSource))
"success": false,
"message": fmt.Sprintf("Bad request. The following source of your scenario ID is not valid: %s", screnarioIDSource),
})
return false, so return false, so
} }
@ -66,10 +53,7 @@ func CheckPermissions(c *gin.Context, operation common.CRUD, screnarioIDSource s
} }
if so.checkAccess(userID.(uint), userRole.(string)) == false { if so.checkAccess(userID.(uint), userRole.(string)) == false {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, "Access denied (for scenario ID).")
"success": false,
"message": "Access denied (for scenario ID).",
})
return false, so return false, so
} }

View file

@ -24,7 +24,7 @@ type ScenarioRequest struct {
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
db = common.DummyInitDB() db = common.InitDB(common.DB_TEST)
defer db.Close() defer db.Close()
router = gin.Default() router = gin.Default()
@ -41,7 +41,7 @@ func TestAddScenario(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as normal user // authenticate as normal user
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -93,7 +93,7 @@ func TestUpdateScenario(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as normal user // authenticate as normal user
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -156,7 +156,7 @@ func TestGetAllScenariosAsAdmin(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as admin // authenticate as admin
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -217,7 +217,7 @@ func TestGetAllScenariosAsUser(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as normal userB // authenticate as normal userB
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -274,7 +274,7 @@ func TestDeleteScenario(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as normal user // authenticate as normal user
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -323,7 +323,7 @@ func TestAddUserToScenario(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as normal user // authenticate as normal user
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -378,7 +378,7 @@ func TestGetAllUsersOfScenario(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as normal user // authenticate as normal user
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -423,7 +423,7 @@ func TestRemoveUserFromScenario(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as normal user // authenticate as normal user
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,

View file

@ -1,7 +1,6 @@
package signal package signal
import ( import (
"fmt"
"net/http" "net/http"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -44,10 +43,7 @@ func getSignals(c *gin.Context) {
} else if direction == "out" { } else if direction == "out" {
mapping = "OutputMapping" mapping = "OutputMapping"
} else { } else {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, "Bad request. Direction has to be in or out")
"success": false,
"error": "Bad request. Direction has to be in or out",
})
return return
} }
@ -58,9 +54,7 @@ func getSignals(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"signals": sigs})
"signals": sigs,
})
} }
// AddSignal godoc // AddSignal godoc
@ -80,19 +74,13 @@ func addSignal(c *gin.Context) {
var req addSignalRequest var req addSignalRequest
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
// Validate the request // Validate the request
if err := req.validate(); err != nil { if err := req.validate(); err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
@ -111,9 +99,7 @@ func addSignal(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"signal": newSignal.Signal})
"signal": newSignal.Signal,
})
} }
// updateSignal godoc // updateSignal godoc
@ -137,29 +123,20 @@ func updateSignal(c *gin.Context) {
var req updateSignalRequest var req updateSignalRequest
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
// Validate the request // Validate the request
if err := req.validate(); err != nil { if err := req.validate(); err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
// Create the updatedSignal from oldDashboard // Create the updatedSignal from oldDashboard
updatedSignal, err := req.updatedSignal(oldSignal) updatedSignal, err := req.updatedSignal(oldSignal)
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
@ -170,9 +147,7 @@ func updateSignal(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"signal": updatedSignal.Signal})
"signal": updatedSignal.Signal,
})
} }
// getSignal godoc // getSignal godoc
@ -193,9 +168,7 @@ func getSignal(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"signal": sig.Signal})
"signal": sig.Signal,
})
} }
// deleteSignal godoc // deleteSignal godoc
@ -223,7 +196,5 @@ func deleteSignal(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"signal": sig.Signal})
"signal": sig.Signal,
})
} }

View file

@ -2,7 +2,6 @@ package signal
import ( import (
"fmt" "fmt"
"net/http"
"strconv" "strconv"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -17,19 +16,13 @@ func checkPermissions(c *gin.Context, operation common.CRUD) (bool, Signal) {
err := common.ValidateRole(c, common.ModelSignal, operation) err := common.ValidateRole(c, common.ModelSignal, operation)
if err != nil { if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, fmt.Sprintf("Access denied (role validation failed): %v", err.Error()))
"success": false,
"message": fmt.Sprintf("Access denied (role validation failed): %v", err),
})
return false, sig return false, sig
} }
signalID, err := strconv.Atoi(c.Param("signalID")) signalID, err := strconv.Atoi(c.Param("signalID"))
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, fmt.Sprintf("No or incorrect format of signalID path parameter"))
"success": false,
"error": fmt.Sprintf("Bad request. No or incorrect format of signalID path parameter"),
})
return false, sig return false, sig
} }

View file

@ -101,7 +101,7 @@ func addScenarioAndSimulatorAndSimulationModel() (scenarioID uint, simulatorID u
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
db = common.DummyInitDB() db = common.InitDB(common.DB_TEST)
defer db.Close() defer db.Close()
router = gin.Default() router = gin.Default()
@ -126,7 +126,7 @@ func TestMain(m *testing.M) {
func TestAddSignal(t *testing.T) { func TestAddSignal(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// prepare the content of the DB for testing // prepare the content of the DB for testing
// by adding a scenario and a simulator to the DB // by adding a scenario and a simulator to the DB
@ -184,7 +184,7 @@ func TestAddSignal(t *testing.T) {
func TestUpdateSignal(t *testing.T) { func TestUpdateSignal(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// prepare the content of the DB for testing // prepare the content of the DB for testing
// by adding a scenario and a simulator to the DB // by adding a scenario and a simulator to the DB
@ -248,7 +248,7 @@ func TestUpdateSignal(t *testing.T) {
func TestDeleteSignal(t *testing.T) { func TestDeleteSignal(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// prepare the content of the DB for testing // prepare the content of the DB for testing
// by adding a scenario and a simulator to the DB // by adding a scenario and a simulator to the DB
@ -316,7 +316,7 @@ func TestDeleteSignal(t *testing.T) {
func TestGetAllInputSignalsOfSimulationModel(t *testing.T) { func TestGetAllInputSignalsOfSimulationModel(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// prepare the content of the DB for testing // prepare the content of the DB for testing
// by adding a scenario and a simulator to the DB // by adding a scenario and a simulator to the DB

View file

@ -1,7 +1,6 @@
package simulationmodel package simulationmodel
import ( import (
"fmt"
"net/http" "net/http"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -43,9 +42,7 @@ func getSimulationModels(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"models": models})
"models": models,
})
} }
// addSimulationModel godoc // addSimulationModel godoc
@ -67,19 +64,13 @@ func addSimulationModel(c *gin.Context) {
var req addSimulationModelRequest var req addSimulationModelRequest
err := c.ShouldBindJSON(&req) err := c.ShouldBindJSON(&req)
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, "Bad request. Error binding form data to JSON: "+err.Error())
"success": false,
"message": "Bad request. Error binding form data to JSON: " + err.Error(),
})
return return
} }
// validate the request // validate the request
if err = req.validate(); err != nil { if err = req.validate(); err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
@ -99,9 +90,7 @@ func addSimulationModel(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"model": newSimulationModel.SimulationModel})
"model": newSimulationModel.SimulationModel,
})
} }
// updateSimulationModel godoc // updateSimulationModel godoc
@ -128,29 +117,20 @@ func updateSimulationModel(c *gin.Context) {
var req updateSimulationModelRequest var req updateSimulationModelRequest
err := c.BindJSON(&req) err := c.BindJSON(&req)
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, "Error binding form data to JSON: "+err.Error())
"success": false,
"message": "Bad request. Error binding form data to JSON: " + err.Error(),
})
return return
} }
// Validate the request // Validate the request
if err := req.validate(); err != nil { if err := req.validate(); err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
// Create the updatedSimulationModel from oldSimulationModel // Create the updatedSimulationModel from oldSimulationModel
updatedSimulationModel, err := req.updatedSimulationModel(oldSimulationModel) updatedSimulationModel, err := req.updatedSimulationModel(oldSimulationModel)
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
@ -161,9 +141,7 @@ func updateSimulationModel(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"model": updatedSimulationModel.SimulationModel})
"model": updatedSimulationModel.SimulationModel,
})
} }
@ -186,9 +164,7 @@ func getSimulationModel(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"model": m.SimulationModel})
"model": m.SimulationModel,
})
} }
// deleteSimulationModel godoc // deleteSimulationModel godoc
@ -215,7 +191,5 @@ func deleteSimulationModel(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"model": m.SimulationModel})
"model": m.SimulationModel,
})
} }

View file

@ -2,7 +2,6 @@ package simulationmodel
import ( import (
"fmt" "fmt"
"net/http"
"strconv" "strconv"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -17,10 +16,7 @@ func CheckPermissions(c *gin.Context, operation common.CRUD, modelIDSource strin
err := common.ValidateRole(c, common.ModelSimulationModel, operation) err := common.ValidateRole(c, common.ModelSimulationModel, operation)
if err != nil { if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, fmt.Sprintf("Access denied (role validation failed): %v", err.Error()))
"success": false,
"message": fmt.Sprintf("Access denied (role validation failed): %v", err),
})
return false, m return false, m
} }
@ -28,20 +24,13 @@ func CheckPermissions(c *gin.Context, operation common.CRUD, modelIDSource strin
if modelIDSource == "path" { if modelIDSource == "path" {
modelID, err = strconv.Atoi(c.Param("modelID")) modelID, err = strconv.Atoi(c.Param("modelID"))
if err != nil { if err != nil {
errormsg := fmt.Sprintf("Bad request. No or incorrect format of modelID path parameter") common.BadRequestError(c, fmt.Sprintf("No or incorrect format of modelID path parameter"))
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": errormsg,
})
return false, m return false, m
} }
} else if modelIDSource == "query" { } else if modelIDSource == "query" {
modelID, err = strconv.Atoi(c.Request.URL.Query().Get("modelID")) modelID, err = strconv.Atoi(c.Request.URL.Query().Get("modelID"))
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, fmt.Sprintf("No or incorrect format of modelID query parameter"))
"success": false,
"message": fmt.Sprintf("Bad request. No or incorrect format of modelID query parameter"),
})
return false, m return false, m
} }
} else if modelIDSource == "body" { } else if modelIDSource == "body" {

View file

@ -79,7 +79,7 @@ func addScenarioAndSimulator() (scenarioID uint, simulatorID uint) {
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
db = common.DummyInitDB() db = common.InitDB(common.DB_TEST)
defer db.Close() defer db.Close()
router = gin.Default() router = gin.Default()
@ -101,7 +101,7 @@ func TestMain(m *testing.M) {
func TestAddSimulationModel(t *testing.T) { func TestAddSimulationModel(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// prepare the content of the DB for testing // prepare the content of the DB for testing
// by adding a scenario and a simulator to the DB // by adding a scenario and a simulator to the DB
@ -160,7 +160,7 @@ func TestUpdateSimulationModel(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// prepare the content of the DB for testing // prepare the content of the DB for testing
// by adding a scenario and a simulator to the DB // by adding a scenario and a simulator to the DB
@ -222,7 +222,7 @@ func TestUpdateSimulationModel(t *testing.T) {
func TestDeleteSimulationModel(t *testing.T) { func TestDeleteSimulationModel(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// prepare the content of the DB for testing // prepare the content of the DB for testing
// by adding a scenario and a simulator to the DB // by adding a scenario and a simulator to the DB
@ -276,7 +276,7 @@ func TestDeleteSimulationModel(t *testing.T) {
func TestGetAllSimulationModelsOfScenario(t *testing.T) { func TestGetAllSimulationModelsOfScenario(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// prepare the content of the DB for testing // prepare the content of the DB for testing
// by adding a scenario and a simulator to the DB // by adding a scenario and a simulator to the DB

View file

@ -1,7 +1,6 @@
package simulator package simulator
import ( import (
"fmt"
"net/http" "net/http"
"time" "time"
@ -47,9 +46,7 @@ func getSimulators(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"simulators": simulators})
"simulators": simulators,
})
} }
// addSimulator godoc // addSimulator godoc
@ -75,20 +72,13 @@ func addSimulator(c *gin.Context) {
var req addSimulatorRequest var req addSimulatorRequest
err := c.BindJSON(&req) err := c.BindJSON(&req)
if err != nil { if err != nil {
errormsg := "Bad request. Error binding form data to JSON: " + err.Error() common.BadRequestError(c, "Error binding form data to JSON: "+err.Error())
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": errormsg,
})
return return
} }
// Validate the request // Validate the request
if err = req.validate(); err != nil { if err = req.validate(); err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
@ -102,9 +92,7 @@ func addSimulator(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"simulator": newSimulator.Simulator})
"simulator": newSimulator.Simulator,
})
} }
// updateSimulator godoc // updateSimulator godoc
@ -131,29 +119,20 @@ func updateSimulator(c *gin.Context) {
var req updateSimulatorRequest var req updateSimulatorRequest
err := c.BindJSON(&req) err := c.BindJSON(&req)
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, "Error binding form data to JSON: "+err.Error())
"success": false,
"message": "Bad request. Error binding form data to JSON: " + err.Error(),
})
return return
} }
// Validate the request // Validate the request
if err = req.validate(); err != nil { if err = req.validate(); err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
// Create the updatedSimulator from oldSimulator // Create the updatedSimulator from oldSimulator
updatedSimulator, err := req.updatedSimulator(oldSimulator) updatedSimulator, err := req.updatedSimulator(oldSimulator)
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
@ -164,9 +143,7 @@ func updateSimulator(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"simulator": updatedSimulator.Simulator})
"simulator": updatedSimulator.Simulator,
})
} }
@ -189,9 +166,7 @@ func getSimulator(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"simulator": s.Simulator})
"simulator": s.Simulator,
})
} }
// deleteSimulator godoc // deleteSimulator godoc
@ -219,9 +194,7 @@ func deleteSimulator(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"simulator": s.Simulator})
"simulator": s.Simulator,
})
} }
// getModelsOfSimulator godoc // getModelsOfSimulator godoc
@ -249,9 +222,7 @@ func getModelsOfSimulator(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"models": allModels})
"models": allModels,
})
} }
// sendActionToSimulator godoc // sendActionToSimulator godoc
@ -277,10 +248,7 @@ func sendActionToSimulator(c *gin.Context) {
var actions []common.Action var actions []common.Action
err := c.BindJSON(&actions) err := c.BindJSON(&actions)
if err != nil { if err != nil {
errormsg := "Bad request. Error binding form data to JSON: " + err.Error() common.BadRequestError(c, "Error binding form data to JSON: "+err.Error())
c.JSON(http.StatusBadRequest, gin.H{
"error": errormsg,
})
return return
} }
@ -293,10 +261,7 @@ func sendActionToSimulator(c *gin.Context) {
err = common.SendActionAMQP(action, s.UUID) err = common.SendActionAMQP(action, s.UUID)
if err != nil { if err != nil {
errormsg := "Internal Server Error. Unable to send actions to simulator: " + err.Error() common.InternalServerError(c, "Unable to send actions to simulator: "+err.Error())
c.JSON(http.StatusInternalServerError, gin.H{
"error": errormsg,
})
return return
} }
} }

View file

@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common" "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"net/http"
"strconv" "strconv"
) )
@ -14,10 +13,7 @@ func checkPermissions(c *gin.Context, modeltype common.ModelName, operation comm
err := common.ValidateRole(c, modeltype, operation) err := common.ValidateRole(c, modeltype, operation)
if err != nil { if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return false, s return false, s
} }
@ -25,10 +21,7 @@ func checkPermissions(c *gin.Context, modeltype common.ModelName, operation comm
// Get the ID of the simulator from the context // Get the ID of the simulator from the context
simulatorID, err := strconv.Atoi(c.Param("simulatorID")) simulatorID, err := strconv.Atoi(c.Param("simulatorID"))
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, fmt.Sprintf("Could not get simulator's ID from context"))
"success": false,
"message": fmt.Sprintf("Could not get simulator's ID from context"),
})
return false, s return false, s
} }

View file

@ -27,7 +27,7 @@ type SimulatorRequest struct {
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
db = common.DummyInitDB() db = common.InitDB(common.DB_TEST)
defer db.Close() defer db.Close()
router = gin.Default() router = gin.Default()
@ -43,7 +43,7 @@ func TestMain(m *testing.M) {
func TestAddSimulatorAsAdmin(t *testing.T) { func TestAddSimulatorAsAdmin(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as admin // authenticate as admin
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -86,7 +86,7 @@ func TestAddSimulatorAsAdmin(t *testing.T) {
func TestAddSimulatorAsUser(t *testing.T) { func TestAddSimulatorAsUser(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as user // authenticate as user
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -113,7 +113,7 @@ func TestAddSimulatorAsUser(t *testing.T) {
func TestUpdateSimulatorAsAdmin(t *testing.T) { func TestUpdateSimulatorAsAdmin(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as admin // authenticate as admin
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -168,7 +168,7 @@ func TestUpdateSimulatorAsAdmin(t *testing.T) {
func TestUpdateSimulatorAsUser(t *testing.T) { func TestUpdateSimulatorAsUser(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as admin // authenticate as admin
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -210,7 +210,7 @@ func TestUpdateSimulatorAsUser(t *testing.T) {
func TestDeleteSimulatorAsAdmin(t *testing.T) { func TestDeleteSimulatorAsAdmin(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as admin // authenticate as admin
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -260,7 +260,7 @@ func TestDeleteSimulatorAsAdmin(t *testing.T) {
func TestDeleteSimulatorAsUser(t *testing.T) { func TestDeleteSimulatorAsUser(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as admin // authenticate as admin
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -301,7 +301,7 @@ func TestDeleteSimulatorAsUser(t *testing.T) {
func TestGetAllSimulators(t *testing.T) { func TestGetAllSimulators(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as admin // authenticate as admin
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -362,7 +362,7 @@ func TestGetAllSimulators(t *testing.T) {
func TestGetSimulationModelsOfSimulator(t *testing.T) { func TestGetSimulationModelsOfSimulator(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as admin // authenticate as admin
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,

View file

@ -0,0 +1,95 @@
package user
import (
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
"net/http"
"time"
)
type tokenClaims struct {
UserID uint `json:"id"`
Role string `json:"role"`
jwt.StandardClaims
}
func RegisterAuthenticate(r *gin.RouterGroup) {
r.POST("", authenticate)
}
// authenticate godoc
// @Summary Authentication for user
// @ID authenticate
// @Accept json
// @Produce json
// @Tags authentication
// @Param inputUser body user.loginRequest true "loginRequest of user"
// @Success 200 {object} docs.ResponseAuthenticate "JSON web token, success status, message and authenticated user object"
// @Failure 400 {object} docs.ResponseError "Bad request"
// @Failure 401 {object} docs.ResponseError "Unauthorized"
// @Failure 404 {object} docs.ResponseError "Not found"
// @Failure 422 {object} docs.ResponseError "Unprocessable entity."
// @Router /authenticate [post]
func authenticate(c *gin.Context) {
// Bind the response (context) with the loginRequest struct
var credentials loginRequest
if err := c.ShouldBindJSON(&credentials); err != nil {
common.UnprocessableEntityError(c, err.Error())
return
}
// Validate the login request
if errs := credentials.validate(); errs != nil {
common.BadRequestError(c, errs.Error())
return
}
// Check if the Username or Password are empty
if credentials.Username == "" || credentials.Password == "" {
common.UnauthorizedError(c, "Invalid credentials")
return
}
// Find the username in the database
var user User
err := user.ByUsername(credentials.Username)
if err != nil {
common.NotFoundError(c, "User not found")
return
}
// Validate the password
err = user.validatePassword(credentials.Password)
if err != nil {
common.UnauthorizedError(c, "Invalid password")
return
}
// create authentication token
claims := tokenClaims{
user.ID,
user.Role,
jwt.StandardClaims{
ExpiresAt: time.Now().Add(weekHours).Unix(),
IssuedAt: time.Now().Unix(),
Issuer: "http://web.villas.fein-aachen.org/",
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, err := token.SignedString([]byte(jwtSigningSecret))
if err != nil {
common.UnprocessableEntityError(c, err.Error())
return
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"message": "Authenticated",
"token": tokenString,
"user": user.User,
})
}

View file

@ -7,7 +7,6 @@ import (
"strings" "strings"
"time" "time"
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common" "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
@ -18,16 +17,6 @@ import (
const jwtSigningSecret = "This should NOT be here!!@33$8&" const jwtSigningSecret = "This should NOT be here!!@33$8&"
const weekHours = time.Hour * 24 * 7 const weekHours = time.Hour * 24 * 7
type tokenClaims struct {
UserID uint `json:"id"`
Role string `json:"role"`
jwt.StandardClaims
}
func RegisterAuthenticate(r *gin.RouterGroup) {
r.POST("", authenticate)
}
func RegisterUserEndpoints(r *gin.RouterGroup) { func RegisterUserEndpoints(r *gin.RouterGroup) {
r.POST("", addUser) r.POST("", addUser)
r.PUT("/:userID", updateUser) r.PUT("/:userID", updateUser)
@ -36,100 +25,6 @@ func RegisterUserEndpoints(r *gin.RouterGroup) {
r.DELETE("/:userID", deleteUser) r.DELETE("/:userID", deleteUser)
} }
// authenticate godoc
// @Summary Authentication for user
// @ID authenticate
// @Accept json
// @Produce json
// @Tags users
// @Param inputUser body user.loginRequest true "loginRequest of user"
// @Success 200 {object} docs.ResponseAuthenticate "JSON web token, success status, message and authenticated user object"
// @Failure 400 {object} docs.ResponseError "Bad request"
// @Failure 401 {object} docs.ResponseError "Unauthorized"
// @Failure 404 {object} docs.ResponseError "Not found"
// @Failure 422 {object} docs.ResponseError "Unprocessable entity."
// @Router /authenticate [post]
func authenticate(c *gin.Context) {
// Bind the response (context) with the loginRequest struct
var credentials loginRequest
if err := c.ShouldBindJSON(&credentials); err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
return
}
// Validate the login request
if errs := credentials.validate(); errs != nil {
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": fmt.Sprintf("%v", errs),
})
return
}
// Check if the Username or Password are empty
if credentials.Username == "" || credentials.Password == "" {
c.JSON(http.StatusUnauthorized, gin.H{
"success": false,
"message": "Invalid credentials",
})
return
}
// Find the username in the database
var user User
err := user.ByUsername(credentials.Username)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{
"success": false,
"message": "User not found",
})
return
}
// Validate the password
err = user.validatePassword(credentials.Password)
if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{
"success": false,
"message": "Invalid password",
})
return
}
// create authentication token
claims := tokenClaims{
user.ID,
user.Role,
jwt.StandardClaims{
ExpiresAt: time.Now().Add(weekHours).Unix(),
IssuedAt: time.Now().Unix(),
Issuer: "http://web.villas.fein-aachen.org/",
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, err := token.SignedString([]byte(jwtSigningSecret))
if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
return
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"message": "Authenticated",
"token": tokenString,
"user": user.User,
})
}
// GetUsers godoc // GetUsers godoc
// @Summary Get all users // @Summary Get all users
// @ID GetUsers // @ID GetUsers
@ -144,10 +39,7 @@ func getUsers(c *gin.Context) {
err := common.ValidateRole(c, common.ModelUsers, common.Read) err := common.ValidateRole(c, common.ModelUsers, common.Read)
if err != nil { if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
@ -158,9 +50,7 @@ func getUsers(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"users": users})
"users": users,
})
} }
// AddUser godoc // AddUser godoc
@ -179,29 +69,20 @@ func addUser(c *gin.Context) {
err := common.ValidateRole(c, common.ModelUser, common.Create) err := common.ValidateRole(c, common.ModelUser, common.Create)
if err != nil { if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
// Bind the request // Bind the request
var req addUserRequest var req addUserRequest
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
// Validate the request // Validate the request
if err = req.validate(); err != nil { if err = req.validate(); err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
@ -211,20 +92,14 @@ func addUser(c *gin.Context) {
// Check that the username is NOT taken // Check that the username is NOT taken
err = newUser.ByUsername(newUser.Username) err = newUser.ByUsername(newUser.Username)
if err == nil { if err == nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, "Username is already taken")
"success": false,
"message": "Username is already taken",
})
return return
} }
// Hash the password before saving it to the DB // Hash the password before saving it to the DB
err = newUser.setPassword(newUser.Password) err = newUser.setPassword(newUser.Password)
if err != nil { if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, "Unable to encrypt the password")
"success": false,
"message": "Unable to encrypt the password",
})
return return
} }
@ -235,9 +110,7 @@ func addUser(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"user": newUser.User})
"user": newUser.User,
})
} }
// UpdateUser godoc // UpdateUser godoc
@ -259,10 +132,7 @@ func updateUser(c *gin.Context) {
err := common.ValidateRole(c, common.ModelUser, common.Update) err := common.ValidateRole(c, common.ModelUser, common.Update)
if err != nil { if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
@ -270,10 +140,7 @@ func updateUser(c *gin.Context) {
var oldUser User var oldUser User
toBeUpdatedID, err := strconv.Atoi(c.Param("userID")) toBeUpdatedID, err := strconv.Atoi(c.Param("userID"))
if err != nil { if err != nil {
c.JSON(http.StatusNotFound, gin.H{ common.NotFoundError(c, fmt.Sprintf("Could not get user's ID from context"))
"success": false,
"message": fmt.Sprintf("Could not get user's ID from context"),
})
return return
} }
@ -296,47 +163,32 @@ func updateUser(c *gin.Context) {
// Get caller's ID from context // Get caller's ID from context
callerID, exists := c.Get(common.UserIDCtx) callerID, exists := c.Get(common.UserIDCtx)
if !exists { if !exists {
c.JSON(http.StatusNotFound, gin.H{ common.NotFoundError(c, fmt.Sprintf("Could not get caller's ID from context"))
"success": false,
"message": fmt.Sprintf("Could not get caller's ID from context"),
})
return return
} }
// Get caller's Role from context // Get caller's Role from context
callerRole, exists := c.Get(common.UserRoleCtx) callerRole, exists := c.Get(common.UserRoleCtx)
if !exists { if !exists {
c.JSON(http.StatusNotFound, gin.H{ common.NotFoundError(c, fmt.Sprintf("Could not get caller's Role from context"))
"success": false,
"message": fmt.Sprintf("Could not get caller's Role from context"),
})
return return
} }
if uint(toBeUpdatedID) != callerID && callerRole != "Admin" { if uint(toBeUpdatedID) != callerID && callerRole != "Admin" {
c.JSON(http.StatusForbidden, gin.H{ common.ForbiddenError(c, "Invalid authorization")
"success": false,
"message": "Invalid authorization",
})
return return
} }
// Bind the (context) with the updateUserRequest struct // Bind the (context) with the updateUserRequest struct
var req updateUserRequest var req updateUserRequest
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, fmt.Sprintf("%v", err))
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
// Validate the request based on struct updateUserRequest json tags // Validate the request based on struct updateUserRequest json tags
if err = req.validate(); err != nil { if err = req.validate(); err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
@ -345,16 +197,10 @@ func updateUser(c *gin.Context) {
updatedUser, err := req.updatedUser(callerRole, oldUser) updatedUser, err := req.updatedUser(callerRole, oldUser)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "Admin") { if strings.Contains(err.Error(), "Admin") {
c.JSON(http.StatusForbidden, gin.H{ common.ForbiddenError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
} else if strings.Contains(err.Error(), "Username") || strings.Contains(err.Error(), "password") { } else if strings.Contains(err.Error(), "Username") || strings.Contains(err.Error(), "password") {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
} }
return return
} }
@ -366,9 +212,7 @@ func updateUser(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"user": updatedUser.User})
"user": updatedUser.User,
})
} }
// GetUser godoc // GetUser godoc
@ -387,19 +231,13 @@ func getUser(c *gin.Context) {
err := common.ValidateRole(c, common.ModelUser, common.Read) err := common.ValidateRole(c, common.ModelUser, common.Read)
if err != nil { if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
id, err := strconv.Atoi(c.Param("userID")) id, err := strconv.Atoi(c.Param("userID"))
if err != nil { if err != nil {
c.JSON(http.StatusNotFound, gin.H{ common.NotFoundError(c, fmt.Sprintf("Could not get user's ID from context"))
"success": false,
"message": fmt.Sprintf("Could not get user's ID from context"),
})
return return
} }
@ -407,10 +245,7 @@ func getUser(c *gin.Context) {
reqUserRole, _ := c.Get(common.UserRoleCtx) reqUserRole, _ := c.Get(common.UserRoleCtx)
if id != reqUserID && reqUserRole != "Admin" { if id != reqUserID && reqUserRole != "Admin" {
c.JSON(http.StatusForbidden, gin.H{ common.ForbiddenError(c, "Invalid authorization")
"success": false,
"message": "Invalid authorization",
})
return return
} }
@ -421,9 +256,7 @@ func getUser(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"user": user.User})
"user": user.User,
})
} }
// DeleteUser godoc // DeleteUser godoc
@ -441,20 +274,14 @@ func deleteUser(c *gin.Context) {
err := common.ValidateRole(c, common.ModelUser, common.Delete) err := common.ValidateRole(c, common.ModelUser, common.Delete)
if err != nil { if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
var user User var user User
id, err := strconv.Atoi(c.Param("userID")) id, err := strconv.Atoi(c.Param("userID"))
if err != nil { if err != nil {
c.JSON(http.StatusNotFound, gin.H{ common.NotFoundError(c, fmt.Sprintf("Could not get user's ID from context"))
"success": false,
"message": fmt.Sprintf("Could not get user's ID from context"),
})
return return
} }
@ -472,7 +299,5 @@ func deleteUser(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"user": user.User})
"user": user.User,
})
} }

View file

@ -6,7 +6,6 @@ import (
"github.com/dgrijalva/jwt-go" "github.com/dgrijalva/jwt-go"
"github.com/dgrijalva/jwt-go/request" "github.com/dgrijalva/jwt-go/request"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"net/http"
) )
func userToContext(ctx *gin.Context, user_id uint) { func userToContext(ctx *gin.Context, user_id uint) {
@ -15,10 +14,7 @@ func userToContext(ctx *gin.Context, user_id uint) {
err := user.ByID(user_id) err := user.ByID(user_id)
if err != nil { if err != nil {
ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{ common.UnauthorizedAbort(ctx, "Authentication failed (user not found)")
"succes": false,
"message": "Authentication failed (user not found)",
})
return return
} }
@ -52,10 +48,7 @@ func Authentication(unauthorized bool) gin.HandlerFunc {
// If the authentication extraction fails return HTTP CODE 401 // If the authentication extraction fails return HTTP CODE 401
if err != nil { if err != nil {
if unauthorized { if unauthorized {
ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{ common.UnauthorizedAbort(ctx, "Authentication failed (claims extraction)")
"succes": false,
"message": "Authentication failed (claims extraction)",
})
} }
return return
} }
@ -66,10 +59,7 @@ func Authentication(unauthorized bool) gin.HandlerFunc {
user_id, ok := claims["id"].(float64) user_id, ok := claims["id"].(float64)
if !ok { if !ok {
ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{ common.UnauthorizedAbort(ctx, "Authentication failed (claims casting)")
"succes": false,
"message": "Authentication failed (claims casting)",
})
return return
} }

View file

@ -24,7 +24,7 @@ type UserRequest struct {
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
db = common.DummyInitDB() db = common.InitDB(common.DB_TEST)
defer db.Close() defer db.Close()
router = gin.Default() router = gin.Default()
@ -41,7 +41,7 @@ func TestAddGetUser(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminDB(db) common.DBAddAdminUser(db)
// authenticate as admin // authenticate as admin
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -89,7 +89,7 @@ func TestUsersNotAllowedActions(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminDB(db) common.DBAddAdminUser(db)
// authenticate as admin // authenticate as admin
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -149,7 +149,7 @@ func TestGetAllUsers(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminDB(db) common.DBAddAdminUser(db)
// authenticate as admin // authenticate as admin
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -185,7 +185,7 @@ func TestModifyAddedUserAsUser(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminDB(db) common.DBAddAdminUser(db)
// authenticate as admin // authenticate as admin
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -296,7 +296,7 @@ func TestInvalidUserUpdate(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminDB(db) common.DBAddAdminUser(db)
// authenticate as admin // authenticate as admin
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -347,7 +347,7 @@ func TestModifyAddedUserAsAdmin(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminDB(db) common.DBAddAdminUser(db)
// authenticate as admin // authenticate as admin
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -429,7 +429,7 @@ func TestDeleteUser(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminDB(db) common.DBAddAdminUser(db)
// authenticate as admin // authenticate as admin
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,

View file

@ -1,7 +1,6 @@
package widget package widget
import ( import (
"fmt"
"net/http" "net/http"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -43,9 +42,7 @@ func getWidgets(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"widgets": widgets})
"widgets": widgets,
})
} }
// addWidget godoc // addWidget godoc
@ -65,19 +62,13 @@ func addWidget(c *gin.Context) {
var req addWidgetRequest var req addWidgetRequest
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
// Validate the request // Validate the request
if err := req.validate(); err != nil { if err := req.validate(); err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
@ -96,9 +87,7 @@ func addWidget(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"widget": newWidget.Widget})
"widget": newWidget.Widget,
})
} }
// updateWidget godoc // updateWidget godoc
@ -124,29 +113,20 @@ func updateWidget(c *gin.Context) {
var req updateWidgetRequest var req updateWidgetRequest
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
// Validate the request // Validate the request
if err := req.validate(); err != nil { if err := req.validate(); err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
// Create the updatedScenario from oldScenario // Create the updatedScenario from oldScenario
updatedWidget, err := req.updatedWidget(oldWidget) updatedWidget, err := req.updatedWidget(oldWidget)
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{ common.BadRequestError(c, err.Error())
"success": false,
"message": fmt.Sprintf("%v", err),
})
return return
} }
@ -157,9 +137,7 @@ func updateWidget(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"widget": updatedWidget.Widget})
"widget": updatedWidget.Widget,
})
} }
@ -182,9 +160,7 @@ func getWidget(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"widget": w.Widget})
"widget": w.Widget,
})
} }
// deleteWidget godoc // deleteWidget godoc
@ -211,7 +187,5 @@ func deleteWidget(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{"widget": w.Widget})
"widget": w.Widget,
})
} }

View file

@ -2,7 +2,6 @@ package widget
import ( import (
"fmt" "fmt"
"net/http"
"strconv" "strconv"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -17,10 +16,7 @@ func CheckPermissions(c *gin.Context, operation common.CRUD, widgetIDBody int) (
err := common.ValidateRole(c, common.ModelWidget, operation) err := common.ValidateRole(c, common.ModelWidget, operation)
if err != nil { if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{ common.UnprocessableEntityError(c, fmt.Sprintf("Access denied (role validation failed): %v", err.Error()))
"success": false,
"message": fmt.Sprintf("Access denied (role validation failed): %v", err),
})
return false, w return false, w
} }
@ -28,11 +24,7 @@ func CheckPermissions(c *gin.Context, operation common.CRUD, widgetIDBody int) (
if widgetIDBody < 0 { if widgetIDBody < 0 {
widgetID, err = strconv.Atoi(c.Param("widgetID")) widgetID, err = strconv.Atoi(c.Param("widgetID"))
if err != nil { if err != nil {
common.BadRequestError(c, fmt.Sprintf("No or incorrect format of widgetID path parameter"))
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": fmt.Sprintf("Bad request. No or incorrect format of widgetID path parameter"),
})
return false, w return false, w
} }
} else { } else {

View file

@ -75,7 +75,7 @@ func addScenarioAndDashboard(token string) (scenarioID uint, dashboardID uint) {
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
db = common.DummyInitDB() db = common.InitDB(common.DB_TEST)
defer db.Close() defer db.Close()
router = gin.Default() router = gin.Default()
@ -97,7 +97,7 @@ func TestMain(m *testing.M) {
func TestAddWidget(t *testing.T) { func TestAddWidget(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as normal user // authenticate as normal user
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -159,7 +159,7 @@ func TestAddWidget(t *testing.T) {
func TestUpdateWidget(t *testing.T) { func TestUpdateWidget(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as normal user // authenticate as normal user
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -232,7 +232,7 @@ func TestUpdateWidget(t *testing.T) {
func TestDeleteWidget(t *testing.T) { func TestDeleteWidget(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as normal user // authenticate as normal user
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,
@ -291,7 +291,7 @@ func TestDeleteWidget(t *testing.T) {
func TestGetAllWidgetsOfDashboard(t *testing.T) { func TestGetAllWidgetsOfDashboard(t *testing.T) {
common.DropTables(db) common.DropTables(db)
common.MigrateModels(db) common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db) common.DBAddAdminAndUser(db)
// authenticate as normal user // authenticate as normal user
token, err := common.AuthenticateForTest(router, token, err := common.AuthenticateForTest(router,

View file

@ -37,12 +37,13 @@ import (
// @host localhost:4000 // @host localhost:4000
// @BasePath /api/v2 // @BasePath /api/v2
func main() { func main() {
// Testing // TODO DB_TEST is used for testing, should be DB_NAME in production
db := common.DummyInitDB() db := common.InitDB(common.DB_TEST)
common.MigrateModels(db) common.MigrateModels(db)
defer db.Close() defer db.Close()
common.DummyPopulateDB(db) // TODO the following line should be removed in production, it adds test data to the DB
common.AddTestData(db)
r := gin.Default() r := gin.Default()