- 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 (
"flag"
"fmt"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres"
"log"
"net/http"
)
var DB_HOST string
var DB_NAME string
var DB_DUMMY string
var DB_SSLMODE string
var WITH_AMQP bool
var DB_HOST string // host of the database system
var DB_NAME string // name of the production database
var DB_TEST string // name of the test database
var DB_SSLMODE string // set to enable if database uses SSL
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
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_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.BoolVar(&WITH_AMQP, "amqp", false, "If AMQP client for simulators shall be enabled, set this option to true (default is false)")
flag.Parse()
fmt.Println("DB_HOST has value ", DB_HOST)
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("WITH_AMQP has value ", WITH_AMQP)
}
// Initialize connection to the database
func InitDB() *gorm.DB {
func InitDB(dbname string) *gorm.DB {
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)
checkErr(err)
DBpool = db
if dbname == DB_TEST {
// if we are using the test DB
// drop tables from previous tests
DropTables(db)
}
return db
}
@ -48,11 +53,6 @@ func GetDB() *gorm.DB {
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
// TODO: Remove that function from the codebase and substitute the body
// to the Dummy*() where it is called
@ -65,6 +65,7 @@ func DropTables(db *gorm.DB) {
db.DropTableIfExists(&User{})
db.DropTableIfExists(&Dashboard{})
db.DropTableIfExists(&Widget{})
// The following statement deletes the many to many relationship between users and scenarios
db.DropTableIfExists("user_scenarios")
}
@ -80,133 +81,6 @@ func MigrateModels(db *gorm.DB) {
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
// NOTE: maybe this is not a good idea
func checkErr(err error) {
@ -214,23 +88,3 @@ func checkErr(err error) {
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
func TestMain(m *testing.M) {
db = DummyInitDB()
db = InitDB(DB_TEST)
// Verify that you can connect to the database
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"
"fmt"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
"github.com/jinzhu/gorm/dialects/postgres"
"github.com/nsf/jsondiff"
"golang.org/x/crypto/bcrypt"
@ -404,3 +405,111 @@ func AuthenticateForTest(router *gin.Engine, url string,
// Return the token and nil error
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
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
@ -44,9 +43,7 @@ func getDashboards(c *gin.Context) {
return
}
c.JSON(http.StatusOK, gin.H{
"dashboards": dab,
})
c.JSON(http.StatusOK, gin.H{"dashboards": dab})
}
// addDashboard godoc
@ -67,19 +64,13 @@ func addDashboard(c *gin.Context) {
// bind request to JSON
var req addDashboardRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
common.BadRequestError(c, err.Error())
return
}
// Validate the request
if err := req.validate(); err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
common.UnprocessableEntityError(c, err.Error())
return
}
@ -99,10 +90,7 @@ func addDashboard(c *gin.Context) {
return
}
c.JSON(http.StatusOK, gin.H{
"dashboard": newDashboard.Dashboard,
})
c.JSON(http.StatusOK, gin.H{"dashboard": newDashboard.Dashboard})
}
// updateDashboard godoc
@ -128,28 +116,19 @@ func updateDashboard(c *gin.Context) {
var req updateDashboardRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
common.BadRequestError(c, err.Error())
return
}
// Validate the request
if err := req.validate(); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
common.BadRequestError(c, err.Error())
return
}
// Create the updatedDashboard from oldDashboard
updatedDashboard, err := req.updatedDashboard(oldDashboard)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
common.BadRequestError(c, err.Error())
return
}
@ -160,10 +139,7 @@ func updateDashboard(c *gin.Context) {
return
}
c.JSON(http.StatusOK, gin.H{
"dashboard": updatedDashboard.Dashboard,
})
c.JSON(http.StatusOK, gin.H{"dashboard": updatedDashboard.Dashboard})
}
// getDashboard godoc
@ -185,9 +161,7 @@ func getDashboard(c *gin.Context) {
return
}
c.JSON(http.StatusOK, gin.H{
"dashboard": dab.Dashboard,
})
c.JSON(http.StatusOK, gin.H{"dashboard": dab.Dashboard})
}
// deleteDashboard godoc
@ -213,7 +187,5 @@ func deleteDashboard(c *gin.Context) {
return
}
c.JSON(http.StatusOK, gin.H{
"dashboard": dab.Dashboard,
})
c.JSON(http.StatusOK, gin.H{"dashboard": dab.Dashboard})
}

View file

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

View file

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

View file

@ -36,19 +36,13 @@ func getFiles(c *gin.Context) {
objectType := c.Request.URL.Query().Get("objectType")
if objectType != "model" && objectType != "widget" {
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": fmt.Sprintf("Bad request. Object type not supported for files: %s", objectType),
})
common.BadRequestError(c, fmt.Sprintf("Object type not supported for files: %s", objectType))
return
}
objectID_s := c.Request.URL.Query().Get("objectID")
objectID, err := strconv.Atoi(objectID_s)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": fmt.Sprintf("Bad request. Error on ID conversion: %s", err.Error()),
})
common.BadRequestError(c, fmt.Sprintf("Error on ID conversion: %s", err.Error()))
return
}
@ -84,10 +78,7 @@ func getFiles(c *gin.Context) {
}
}
c.JSON(http.StatusOK, gin.H{
"files": files,
})
c.JSON(http.StatusOK, gin.H{"files": files})
}
// addFile godoc
@ -114,19 +105,13 @@ func addFile(c *gin.Context) {
objectType := c.Request.URL.Query().Get("objectType")
if objectType != "model" && objectType != "widget" {
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": fmt.Sprintf("Bad request. Object type not supported for files: %s", objectType),
})
common.BadRequestError(c, fmt.Sprintf("Object type not supported for files: %s", objectType))
return
}
objectID_s := c.Request.URL.Query().Get("objectID")
objectID, err := strconv.Atoi(objectID_s)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": fmt.Sprintf("Bad request. Error on ID conversion: %s", err.Error()),
})
common.BadRequestError(c, fmt.Sprintf("Error on ID conversion: %s", err.Error()))
return
}
@ -147,10 +132,7 @@ func addFile(c *gin.Context) {
// Extract file from POST request form
file_header, err := c.FormFile("file")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": fmt.Sprintf("Bad request. Get form error: %s", err.Error()),
})
common.BadRequestError(c, fmt.Sprintf("Get form error: %s", err.Error()))
return
}
@ -161,9 +143,7 @@ func addFile(c *gin.Context) {
return
}
c.JSON(http.StatusOK, gin.H{
"file": newFile.File,
})
c.JSON(http.StatusOK, gin.H{"file": newFile.File})
}
// getFile godoc
@ -197,10 +177,7 @@ func getFile(c *gin.Context) {
return
}
c.JSON(http.StatusOK, gin.H{
"file": f.File,
})
c.JSON(http.StatusOK, gin.H{"file": f.File})
}
// updateFile godoc
@ -233,19 +210,13 @@ func updateFile(c *gin.Context) {
// Extract file from PUT request form
err := c.Request.ParseForm()
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": fmt.Sprintf("Bad request. Get form error: %s", err.Error()),
})
common.BadRequestError(c, fmt.Sprintf("Get form error: %s", err.Error()))
return
}
file_header, err := c.FormFile("file")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"error": fmt.Sprintf("Bad request. Get form error: %s", err.Error()),
})
common.BadRequestError(c, fmt.Sprintf("Get form error: %s", err.Error()))
return
}
@ -255,9 +226,7 @@ func updateFile(c *gin.Context) {
return
}
c.JSON(http.StatusOK, gin.H{
"file": f.File,
})
c.JSON(http.StatusOK, gin.H{"file": f.File})
}
// deleteFile godoc
@ -286,7 +255,5 @@ func deleteFile(c *gin.Context) {
return
}
c.JSON(http.StatusOK, gin.H{
"file": f.File,
})
c.JSON(http.StatusOK, gin.H{"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/widget"
"github.com/gin-gonic/gin"
"net/http"
"strconv"
)
@ -16,19 +15,13 @@ func checkPermissions(c *gin.Context, operation common.CRUD) (bool, File) {
err := common.ValidateRole(c, common.ModelFile, operation)
if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{
"success": false,
"message": fmt.Sprintf("Access denied (role validation failed): %v", err),
})
common.UnprocessableEntityError(c, fmt.Sprintf("Access denied (role validation failed): %v", err.Error()))
return false, f
}
fileID, err := strconv.Atoi(c.Param("fileID"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"error": fmt.Sprintf("Bad request. No or incorrect format of fileID path parameter"),
})
common.BadRequestError(c, fmt.Sprintf("No or incorrect format of fileID path parameter"))
return false, f
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -2,7 +2,6 @@ package signal
import (
"fmt"
"net/http"
"strconv"
"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)
if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{
"success": false,
"message": fmt.Sprintf("Access denied (role validation failed): %v", err),
})
common.UnprocessableEntityError(c, fmt.Sprintf("Access denied (role validation failed): %v", err.Error()))
return false, sig
}
signalID, err := strconv.Atoi(c.Param("signalID"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"error": fmt.Sprintf("Bad request. No or incorrect format of signalID path parameter"),
})
common.BadRequestError(c, fmt.Sprintf("No or incorrect format of signalID path parameter"))
return false, sig
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -27,7 +27,7 @@ type SimulatorRequest struct {
func TestMain(m *testing.M) {
db = common.DummyInitDB()
db = common.InitDB(common.DB_TEST)
defer db.Close()
router = gin.Default()
@ -43,7 +43,7 @@ func TestMain(m *testing.M) {
func TestAddSimulatorAsAdmin(t *testing.T) {
common.DropTables(db)
common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db)
common.DBAddAdminAndUser(db)
// authenticate as admin
token, err := common.AuthenticateForTest(router,
@ -86,7 +86,7 @@ func TestAddSimulatorAsAdmin(t *testing.T) {
func TestAddSimulatorAsUser(t *testing.T) {
common.DropTables(db)
common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db)
common.DBAddAdminAndUser(db)
// authenticate as user
token, err := common.AuthenticateForTest(router,
@ -113,7 +113,7 @@ func TestAddSimulatorAsUser(t *testing.T) {
func TestUpdateSimulatorAsAdmin(t *testing.T) {
common.DropTables(db)
common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db)
common.DBAddAdminAndUser(db)
// authenticate as admin
token, err := common.AuthenticateForTest(router,
@ -168,7 +168,7 @@ func TestUpdateSimulatorAsAdmin(t *testing.T) {
func TestUpdateSimulatorAsUser(t *testing.T) {
common.DropTables(db)
common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db)
common.DBAddAdminAndUser(db)
// authenticate as admin
token, err := common.AuthenticateForTest(router,
@ -210,7 +210,7 @@ func TestUpdateSimulatorAsUser(t *testing.T) {
func TestDeleteSimulatorAsAdmin(t *testing.T) {
common.DropTables(db)
common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db)
common.DBAddAdminAndUser(db)
// authenticate as admin
token, err := common.AuthenticateForTest(router,
@ -260,7 +260,7 @@ func TestDeleteSimulatorAsAdmin(t *testing.T) {
func TestDeleteSimulatorAsUser(t *testing.T) {
common.DropTables(db)
common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db)
common.DBAddAdminAndUser(db)
// authenticate as admin
token, err := common.AuthenticateForTest(router,
@ -301,7 +301,7 @@ func TestDeleteSimulatorAsUser(t *testing.T) {
func TestGetAllSimulators(t *testing.T) {
common.DropTables(db)
common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db)
common.DBAddAdminAndUser(db)
// authenticate as admin
token, err := common.AuthenticateForTest(router,
@ -362,7 +362,7 @@ func TestGetAllSimulators(t *testing.T) {
func TestGetSimulationModelsOfSimulator(t *testing.T) {
common.DropTables(db)
common.MigrateModels(db)
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db)
common.DBAddAdminAndUser(db)
// authenticate as admin
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"
"time"
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
"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 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) {
r.POST("", addUser)
r.PUT("/:userID", updateUser)
@ -36,100 +25,6 @@ func RegisterUserEndpoints(r *gin.RouterGroup) {
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
// @Summary Get all users
// @ID GetUsers
@ -144,10 +39,7 @@ func getUsers(c *gin.Context) {
err := common.ValidateRole(c, common.ModelUsers, common.Read)
if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
common.UnprocessableEntityError(c, err.Error())
return
}
@ -158,9 +50,7 @@ func getUsers(c *gin.Context) {
return
}
c.JSON(http.StatusOK, gin.H{
"users": users,
})
c.JSON(http.StatusOK, gin.H{"users": users})
}
// AddUser godoc
@ -179,29 +69,20 @@ func addUser(c *gin.Context) {
err := common.ValidateRole(c, common.ModelUser, common.Create)
if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
common.UnprocessableEntityError(c, err.Error())
return
}
// Bind the request
var req addUserRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
common.BadRequestError(c, err.Error())
return
}
// Validate the request
if err = req.validate(); err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
common.UnprocessableEntityError(c, err.Error())
return
}
@ -211,20 +92,14 @@ func addUser(c *gin.Context) {
// Check that the username is NOT taken
err = newUser.ByUsername(newUser.Username)
if err == nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{
"success": false,
"message": "Username is already taken",
})
common.UnprocessableEntityError(c, "Username is already taken")
return
}
// Hash the password before saving it to the DB
err = newUser.setPassword(newUser.Password)
if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{
"success": false,
"message": "Unable to encrypt the password",
})
common.UnprocessableEntityError(c, "Unable to encrypt the password")
return
}
@ -235,9 +110,7 @@ func addUser(c *gin.Context) {
return
}
c.JSON(http.StatusOK, gin.H{
"user": newUser.User,
})
c.JSON(http.StatusOK, gin.H{"user": newUser.User})
}
// UpdateUser godoc
@ -259,10 +132,7 @@ func updateUser(c *gin.Context) {
err := common.ValidateRole(c, common.ModelUser, common.Update)
if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
common.UnprocessableEntityError(c, err.Error())
return
}
@ -270,10 +140,7 @@ func updateUser(c *gin.Context) {
var oldUser User
toBeUpdatedID, err := strconv.Atoi(c.Param("userID"))
if err != nil {
c.JSON(http.StatusNotFound, gin.H{
"success": false,
"message": fmt.Sprintf("Could not get user's ID from context"),
})
common.NotFoundError(c, fmt.Sprintf("Could not get user's ID from context"))
return
}
@ -296,47 +163,32 @@ func updateUser(c *gin.Context) {
// Get caller's ID from context
callerID, exists := c.Get(common.UserIDCtx)
if !exists {
c.JSON(http.StatusNotFound, gin.H{
"success": false,
"message": fmt.Sprintf("Could not get caller's ID from context"),
})
common.NotFoundError(c, fmt.Sprintf("Could not get caller's ID from context"))
return
}
// Get caller's Role from context
callerRole, exists := c.Get(common.UserRoleCtx)
if !exists {
c.JSON(http.StatusNotFound, gin.H{
"success": false,
"message": fmt.Sprintf("Could not get caller's Role from context"),
})
common.NotFoundError(c, fmt.Sprintf("Could not get caller's Role from context"))
return
}
if uint(toBeUpdatedID) != callerID && callerRole != "Admin" {
c.JSON(http.StatusForbidden, gin.H{
"success": false,
"message": "Invalid authorization",
})
common.ForbiddenError(c, "Invalid authorization")
return
}
// Bind the (context) with the updateUserRequest struct
var req updateUserRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
common.UnprocessableEntityError(c, fmt.Sprintf("%v", err))
return
}
// Validate the request based on struct updateUserRequest json tags
if err = req.validate(); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
common.BadRequestError(c, err.Error())
return
}
@ -345,16 +197,10 @@ func updateUser(c *gin.Context) {
updatedUser, err := req.updatedUser(callerRole, oldUser)
if err != nil {
if strings.Contains(err.Error(), "Admin") {
c.JSON(http.StatusForbidden, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
common.ForbiddenError(c, err.Error())
} else if strings.Contains(err.Error(), "Username") || strings.Contains(err.Error(), "password") {
c.JSON(http.StatusBadRequest, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
common.BadRequestError(c, err.Error())
}
return
}
@ -366,9 +212,7 @@ func updateUser(c *gin.Context) {
return
}
c.JSON(http.StatusOK, gin.H{
"user": updatedUser.User,
})
c.JSON(http.StatusOK, gin.H{"user": updatedUser.User})
}
// GetUser godoc
@ -387,19 +231,13 @@ func getUser(c *gin.Context) {
err := common.ValidateRole(c, common.ModelUser, common.Read)
if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
common.UnprocessableEntityError(c, err.Error())
return
}
id, err := strconv.Atoi(c.Param("userID"))
if err != nil {
c.JSON(http.StatusNotFound, gin.H{
"success": false,
"message": fmt.Sprintf("Could not get user's ID from context"),
})
common.NotFoundError(c, fmt.Sprintf("Could not get user's ID from context"))
return
}
@ -407,10 +245,7 @@ func getUser(c *gin.Context) {
reqUserRole, _ := c.Get(common.UserRoleCtx)
if id != reqUserID && reqUserRole != "Admin" {
c.JSON(http.StatusForbidden, gin.H{
"success": false,
"message": "Invalid authorization",
})
common.ForbiddenError(c, "Invalid authorization")
return
}
@ -421,9 +256,7 @@ func getUser(c *gin.Context) {
return
}
c.JSON(http.StatusOK, gin.H{
"user": user.User,
})
c.JSON(http.StatusOK, gin.H{"user": user.User})
}
// DeleteUser godoc
@ -441,20 +274,14 @@ func deleteUser(c *gin.Context) {
err := common.ValidateRole(c, common.ModelUser, common.Delete)
if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{
"success": false,
"message": fmt.Sprintf("%v", err),
})
common.UnprocessableEntityError(c, err.Error())
return
}
var user User
id, err := strconv.Atoi(c.Param("userID"))
if err != nil {
c.JSON(http.StatusNotFound, gin.H{
"success": false,
"message": fmt.Sprintf("Could not get user's ID from context"),
})
common.NotFoundError(c, fmt.Sprintf("Could not get user's ID from context"))
return
}
@ -472,7 +299,5 @@ func deleteUser(c *gin.Context) {
return
}
c.JSON(http.StatusOK, gin.H{
"user": user.User,
})
c.JSON(http.StatusOK, gin.H{"user": user.User})
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -37,12 +37,13 @@ import (
// @host localhost:4000
// @BasePath /api/v2
func main() {
// Testing
db := common.DummyInitDB()
// TODO DB_TEST is used for testing, should be DB_NAME in production
db := common.InitDB(common.DB_TEST)
common.MigrateModels(db)
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()