diff --git a/routes/widget/widget_endpoints.go b/routes/widget/widget_endpoints.go index ffa6b3e..973b5fb 100644 --- a/routes/widget/widget_endpoints.go +++ b/routes/widget/widget_endpoints.go @@ -39,11 +39,10 @@ func getWidgets(c *gin.Context) { db := database.GetDB() var widgets []database.Widget err := db.Order("ID asc").Model(dab).Related(&widgets, "Widgets").Error - if helper.DBError(c, err) { - return + if !helper.DBError(c, err) { + c.JSON(http.StatusOK, gin.H{"widgets": widgets}) } - c.JSON(http.StatusOK, gin.H{"widgets": widgets}) } // addWidget godoc @@ -77,18 +76,16 @@ func addWidget(c *gin.Context) { newWidget := req.createWidget() // Check if user is allowed to modify selected dashboard (scenario) - ok, _ := dashboard.CheckPermissions(c, database.Create, "body", int(newWidget.DashboardID)) + ok, _ := dashboard.CheckPermissions(c, database.Update, "body", int(newWidget.DashboardID)) if !ok { return } err := newWidget.addToDashboard() - if err != nil { - helper.DBError(c, err) - return + if !helper.DBError(c, err) { + c.JSON(http.StatusOK, gin.H{"widget": newWidget.Widget}) } - c.JSON(http.StatusOK, gin.H{"widget": newWidget.Widget}) } // updateWidget godoc @@ -125,21 +122,14 @@ func updateWidget(c *gin.Context) { } // Create the updatedScenario from oldScenario - updatedWidget, err := req.updatedWidget(oldWidget) - if err != nil { - helper.BadRequestError(c, err.Error()) - return - } + updatedWidget := req.updatedWidget(oldWidget) // Update the widget in the DB - err = oldWidget.update(updatedWidget) - if err != nil { - helper.DBError(c, err) - return + err := oldWidget.update(updatedWidget) + if !helper.DBError(c, err) { + c.JSON(http.StatusOK, gin.H{"widget": updatedWidget.Widget}) } - c.JSON(http.StatusOK, gin.H{"widget": updatedWidget.Widget}) - } // getWidget godoc @@ -184,9 +174,8 @@ func deleteWidget(c *gin.Context) { } err := w.delete() - if helper.DBError(c, err) { - return + if !helper.DBError(c, err) { + c.JSON(http.StatusOK, gin.H{"widget": w.Widget}) } - c.JSON(http.StatusOK, gin.H{"widget": w.Widget}) } diff --git a/routes/widget/widget_test.go b/routes/widget/widget_test.go index 75b8fbf..cf7e0fd 100644 --- a/routes/widget/widget_test.go +++ b/routes/widget/widget_test.go @@ -71,6 +71,10 @@ func addScenarioAndDashboard(token string) (scenarioID uint, dashboardID uint) { // Read newDashboard's ID from the response newDashboardID, _ := helper.GetResponseID(resp) + // add the guest user to the new scenario + _, resp, _ = helper.TestEndpoint(router, token, + fmt.Sprintf("/api/scenarios/%v/user?username=User_C", newScenarioID), "PUT", nil) + return uint(newScenarioID), uint(newDashboardID) } @@ -107,7 +111,6 @@ func TestAddWidget(t *testing.T) { _, dashboardID := addScenarioAndDashboard(token) - // test POST widgets/ $newWidget newWidget := WidgetRequest{ Name: database.WidgetA.Name, Type: database.WidgetA.Type, @@ -122,9 +125,35 @@ func TestAddWidget(t *testing.T) { CustomProperties: database.WidgetA.CustomProperties, DashboardID: dashboardID, } + + // authenticate as userB who has no access to scenario + token, err = helper.AuthenticateForTest(router, + "/api/authenticate", "POST", helper.UserBCredentials) + assert.NoError(t, err) + + // try to POST the newWidget with no access to the scenario + // should result in unprocessable entity code, resp, err := helper.TestEndpoint(router, token, "/api/widgets", "POST", helper.KeyModels{"widget": newWidget}) assert.NoError(t, err) + assert.Equalf(t, 422, code, "Response body: \n%v\n", resp) + + // authenticate as normal user + token, err = helper.AuthenticateForTest(router, + "/api/authenticate", "POST", helper.UserACredentials) + assert.NoError(t, err) + + // try to POST non JSON body + // should result in bad request + code, resp, err = helper.TestEndpoint(router, token, + "/api/widgets", "POST", "This is no JSON") + assert.NoError(t, err) + assert.Equalf(t, 400, code, "Response body: \n%v\n", resp) + + // test POST widgets/ $newWidget + code, resp, err = helper.TestEndpoint(router, token, + "/api/widgets", "POST", helper.KeyModels{"widget": newWidget}) + assert.NoError(t, err) assert.Equalf(t, 200, code, "Response body: \n%v\n", resp) // Compare POST's response with the newWidget @@ -155,6 +184,18 @@ func TestAddWidget(t *testing.T) { "/api/widgets", "POST", helper.KeyModels{"widget": malformedNewWidget}) assert.NoError(t, err) assert.Equalf(t, 422, code, "Response body: \n%v\n", resp) + + // authenticate as userB who has no access to scenario + token, err = helper.AuthenticateForTest(router, + "/api/authenticate", "POST", helper.UserBCredentials) + assert.NoError(t, err) + + // try to GET the newWidget with no access to the scenario + // should result in unprocessable entity + code, resp, err = helper.TestEndpoint(router, token, + fmt.Sprintf("/api/widgets/%v", newWidgetID), "GET", nil) + assert.NoError(t, err) + assert.Equalf(t, 422, code, "Response body: \n%v\n", resp) } func TestUpdateWidget(t *testing.T) { @@ -203,6 +244,43 @@ func TestUpdateWidget(t *testing.T) { CustomProperties: database.WidgetA.CustomProperties, } + // authenticate as userB who has no access to scenario + token, err = helper.AuthenticateForTest(router, + "/api/authenticate", "POST", helper.UserBCredentials) + assert.NoError(t, err) + + // try to PUT the updatedWidget with no access to the scenario + // should result in unprocessable entity + code, resp, err = helper.TestEndpoint(router, token, + fmt.Sprintf("/api/widgets/%v", newWidgetID), "PUT", helper.KeyModels{"widget": updatedWidget}) + assert.NoError(t, err) + assert.Equalf(t, 422, code, "Response body: \n%v\n", resp) + + // authenticate as guest user who has access to simulation model + token, err = helper.AuthenticateForTest(router, + "/api/authenticate", "POST", helper.GuestCredentials) + assert.NoError(t, err) + + // try to PUT as guest + // should NOT work and result in unprocessable entity + code, resp, err = helper.TestEndpoint(router, token, + fmt.Sprintf("/api/widgets/%v", newWidgetID), "PUT", helper.KeyModels{"widget": updatedWidget}) + assert.NoError(t, err) + assert.Equalf(t, 422, code, "Response body: \n%v\n", resp) + + // authenticate as normal user + token, err = helper.AuthenticateForTest(router, + "/api/authenticate", "POST", helper.UserACredentials) + assert.NoError(t, err) + + // try to PUT non JSON body + // should result in bad request + code, resp, err = helper.TestEndpoint(router, token, + fmt.Sprintf("/api/widgets/%v", newWidgetID), "PUT", "This is no JSON") + assert.NoError(t, err) + assert.Equalf(t, 400, code, "Response body: \n%v\n", resp) + + // test PUT code, resp, err = helper.TestEndpoint(router, token, fmt.Sprintf("/api/widgets/%v", newWidgetID), "PUT", helper.KeyModels{"widget": updatedWidget}) assert.NoError(t, err) @@ -266,6 +344,23 @@ func TestDeleteWidget(t *testing.T) { newWidgetID, err := helper.GetResponseID(resp) assert.NoError(t, err) + // authenticate as userB who has no access to scenario + token, err = helper.AuthenticateForTest(router, + "/api/authenticate", "POST", helper.UserBCredentials) + assert.NoError(t, err) + + // try to DELETE the newWidget with no access to the scenario + // should result in unprocessable entity + code, resp, err = helper.TestEndpoint(router, token, + fmt.Sprintf("/api/widgets/%v", newWidgetID), "DELETE", nil) + assert.NoError(t, err) + assert.Equalf(t, 422, code, "Response body: \n%v\n", resp) + + // authenticate as normal user + token, err = helper.AuthenticateForTest(router, + "/api/authenticate", "POST", helper.UserACredentials) + assert.NoError(t, err) + // Count the number of all the widgets returned for dashboard initialNumber, err := helper.LengthOfResponse(router, token, fmt.Sprintf("/api/widgets?dashboardID=%v", dashboardID), "GET", nil) @@ -301,6 +396,23 @@ func TestGetAllWidgetsOfDashboard(t *testing.T) { _, dashboardID := addScenarioAndDashboard(token) + // authenticate as userB who has no access to scenario + token, err = helper.AuthenticateForTest(router, + "/api/authenticate", "POST", helper.UserBCredentials) + assert.NoError(t, err) + + // try to GET all widgets of dashboard + // should result in unprocessable entity + code, resp, err := helper.TestEndpoint(router, token, + fmt.Sprintf("/api/widgets?dashboardID=%v", dashboardID), "GET", nil) + assert.NoError(t, err) + assert.Equalf(t, 422, code, "Response body: \n%v\n", resp) + + // authenticate as normal user + token, err = helper.AuthenticateForTest(router, + "/api/authenticate", "POST", helper.UserACredentials) + assert.NoError(t, err) + // Count the number of all the widgets returned for dashboard initialNumber, err := helper.LengthOfResponse(router, token, fmt.Sprintf("/api/widgets?dashboardID=%v", dashboardID), "GET", nil) @@ -321,7 +433,7 @@ func TestGetAllWidgetsOfDashboard(t *testing.T) { CustomProperties: database.WidgetA.CustomProperties, DashboardID: dashboardID, } - code, resp, err := helper.TestEndpoint(router, token, + code, resp, err = helper.TestEndpoint(router, token, "/api/widgets", "POST", helper.KeyModels{"widget": newWidgetA}) assert.NoError(t, err) assert.Equalf(t, 200, code, "Response body: \n%v\n", resp) diff --git a/routes/widget/widget_validators.go b/routes/widget/widget_validators.go index 21c3ccd..6bda9bf 100644 --- a/routes/widget/widget_validators.go +++ b/routes/widget/widget_validators.go @@ -76,7 +76,7 @@ func (r *addWidgetRequest) createWidget() Widget { return s } -func (r *updateWidgetRequest) updatedWidget(oldWidget Widget) (Widget, error) { +func (r *updateWidgetRequest) updatedWidget(oldWidget Widget) Widget { // Use the old Widget as a basis for the updated Widget `s` s := oldWidget @@ -105,5 +105,5 @@ func (r *updateWidgetRequest) updatedWidget(oldWidget Widget) (Widget, error) { s.CustomProperties = r.CustomProperties } - return s, nil + return s }