Remove Macaron ParamsInt64 function from code base (#43810)

* draft commit

* change all calls

* Compilation errors
This commit is contained in:
ying-jeanne 2022-01-14 17:55:57 +01:00 committed by GitHub
parent bd8791aced
commit 7422789ec7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 454 additions and 131 deletions

View File

@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"net/http"
"strconv"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response"
@ -67,7 +68,11 @@ func AdminUpdateUserPassword(c *models.ReqContext) response.Response {
if err := web.Bind(c.Req, &form); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
userID := c.ParamsInt64(":id")
userID, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
if len(form.Password) < 4 {
return response.Error(400, "New password too short", nil)
@ -102,9 +107,12 @@ func (hs *HTTPServer) AdminUpdateUserPermissions(c *models.ReqContext) response.
if err := web.Bind(c.Req, &form); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
userID := c.ParamsInt64(":id")
userID, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
err := updateUserPermissions(hs.SQLStore, userID, form.IsGrafanaAdmin)
err = updateUserPermissions(hs.SQLStore, userID, form.IsGrafanaAdmin)
if err != nil {
if errors.Is(err, models.ErrLastGrafanaAdmin) {
return response.Error(400, models.ErrLastGrafanaAdmin.Error(), nil)
@ -117,7 +125,10 @@ func (hs *HTTPServer) AdminUpdateUserPermissions(c *models.ReqContext) response.
}
func AdminDeleteUser(c *models.ReqContext) response.Response {
userID := c.ParamsInt64(":id")
userID, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
cmd := models.DeleteUserCommand{UserId: userID}
@ -133,7 +144,10 @@ func AdminDeleteUser(c *models.ReqContext) response.Response {
// POST /api/admin/users/:id/disable
func (hs *HTTPServer) AdminDisableUser(c *models.ReqContext) response.Response {
userID := c.ParamsInt64(":id")
userID, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
// External users shouldn't be disabled from API
authInfoQuery := &models.GetAuthInfoQuery{UserId: userID}
@ -149,7 +163,7 @@ func (hs *HTTPServer) AdminDisableUser(c *models.ReqContext) response.Response {
return response.Error(500, "Failed to disable user", err)
}
err := hs.AuthTokenService.RevokeAllUserTokens(c.Req.Context(), userID)
err = hs.AuthTokenService.RevokeAllUserTokens(c.Req.Context(), userID)
if err != nil {
return response.Error(500, "Failed to disable user", err)
}
@ -159,7 +173,10 @@ func (hs *HTTPServer) AdminDisableUser(c *models.ReqContext) response.Response {
// POST /api/admin/users/:id/enable
func AdminEnableUser(c *models.ReqContext) response.Response {
userID := c.ParamsInt64(":id")
userID, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
// External users shouldn't be disabled from API
authInfoQuery := &models.GetAuthInfoQuery{UserId: userID}
@ -180,7 +197,10 @@ func AdminEnableUser(c *models.ReqContext) response.Response {
// POST /api/admin/users/:id/logout
func (hs *HTTPServer) AdminLogoutUser(c *models.ReqContext) response.Response {
userID := c.ParamsInt64(":id")
userID, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
if c.UserId == userID {
return response.Error(400, "You cannot logout yourself", nil)
@ -191,7 +211,10 @@ func (hs *HTTPServer) AdminLogoutUser(c *models.ReqContext) response.Response {
// GET /api/admin/users/:id/auth-tokens
func (hs *HTTPServer) AdminGetUserAuthTokens(c *models.ReqContext) response.Response {
userID := c.ParamsInt64(":id")
userID, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
return hs.getUserAuthTokensInternal(c, userID)
}
@ -201,7 +224,10 @@ func (hs *HTTPServer) AdminRevokeUserAuthToken(c *models.ReqContext) response.Re
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
userID := c.ParamsInt64(":id")
userID, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
return hs.revokeUserAuthTokenInternal(c, userID, cmd)
}

View File

@ -21,7 +21,11 @@ import (
)
func ValidateOrgAlert(c *models.ReqContext) {
id := c.ParamsInt64(":alertId")
id, err := strconv.ParseInt(web.Params(c.Req)[":alertId"], 10, 64)
if err != nil {
c.JsonApiErr(http.StatusBadRequest, "alertId is invalid", nil)
return
}
query := models.GetAlertByIdQuery{Id: id}
if err := bus.Dispatch(c.Req.Context(), &query); err != nil {
@ -178,7 +182,10 @@ func (hs *HTTPServer) AlertTest(c *models.ReqContext) response.Response {
// GET /api/alerts/:id
func GetAlert(c *models.ReqContext) response.Response {
id := c.ParamsInt64(":alertId")
id, err := strconv.ParseInt(web.Params(c.Req)[":alertId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "alertId is invalid", err)
}
query := models.GetAlertByIdQuery{Id: id}
if err := bus.Dispatch(c.Req.Context(), &query); err != nil {
@ -240,9 +247,13 @@ func getAlertNotificationsInternal(c *models.ReqContext) ([]*models.AlertNotific
}
func GetAlertNotificationByID(c *models.ReqContext) response.Response {
notificationId, err := strconv.ParseInt(web.Params(c.Req)[":notificationId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "notificationId is invalid", err)
}
query := &models.GetAlertNotificationsQuery{
OrgId: c.OrgId,
Id: c.ParamsInt64(":notificationId"),
Id: notificationId,
}
if query.Id == 0 {
@ -426,9 +437,14 @@ func (hs *HTTPServer) fillWithSecureSettingsDataByUID(ctx context.Context, cmd *
}
func DeleteAlertNotification(c *models.ReqContext) response.Response {
notificationId, err := strconv.ParseInt(web.Params(c.Req)[":notificationId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "notificationId is invalid", err)
}
cmd := models.DeleteAlertNotificationCommand{
OrgId: c.OrgId,
Id: c.ParamsInt64(":notificationId"),
Id: notificationId,
}
if err := bus.Dispatch(c.Req.Context(), &cmd); err != nil {
@ -496,7 +512,10 @@ func PauseAlert(c *models.ReqContext) response.Response {
if err := web.Bind(c.Req, &dto); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
alertID := c.ParamsInt64(":alertId")
alertID, err := strconv.ParseInt(web.Params(c.Req)[":alertId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "alertId is invalid", err)
}
result := make(map[string]interface{})
result["alertId"] = alertID

View File

@ -3,6 +3,7 @@ package api
import (
"errors"
"net/http"
"strconv"
"strings"
"github.com/grafana/grafana/pkg/api/dtos"
@ -164,7 +165,11 @@ func UpdateAnnotation(c *models.ReqContext) response.Response {
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
annotationID := c.ParamsInt64(":annotationId")
annotationID, err := strconv.ParseInt(web.Params(c.Req)[":annotationId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "annotationId is invalid", err)
}
repo := annotations.GetRepository()
@ -194,7 +199,10 @@ func PatchAnnotation(c *models.ReqContext) response.Response {
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
annotationID := c.ParamsInt64(":annotationId")
annotationID, err := strconv.ParseInt(web.Params(c.Req)[":annotationId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "annotationId is invalid", err)
}
repo := annotations.GetRepository()
@ -264,13 +272,16 @@ func DeleteAnnotations(c *models.ReqContext) response.Response {
func DeleteAnnotationByID(c *models.ReqContext) response.Response {
repo := annotations.GetRepository()
annotationID := c.ParamsInt64(":annotationId")
annotationID, err := strconv.ParseInt(web.Params(c.Req)[":annotationId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "annotationId is invalid", err)
}
if resp := canSave(c, repo, annotationID); resp != nil {
return resp
}
err := repo.Delete(&annotations.DeleteParams{
err = repo.Delete(&annotations.DeleteParams{
OrgId: c.OrgId,
Id: annotationID,
})

View File

@ -3,6 +3,7 @@ package api
import (
"errors"
"net/http"
"strconv"
"time"
"github.com/grafana/grafana/pkg/api/dtos"
@ -41,11 +42,14 @@ func GetAPIKeys(c *models.ReqContext) response.Response {
// DeleteAPIKey deletes an API key
func DeleteAPIKey(c *models.ReqContext) response.Response {
id := c.ParamsInt64(":id")
id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
cmd := &models.DeleteApiKeyCommand{Id: id, OrgId: c.OrgId}
err := bus.Dispatch(c.Req.Context(), cmd)
err = bus.Dispatch(c.Req.Context(), cmd)
if err != nil {
var status int
if errors.Is(err, models.ErrApiKeyNotFound) {

View File

@ -36,8 +36,8 @@ import (
"github.com/grafana/grafana/pkg/web"
)
func loggedInUserScenario(t *testing.T, desc string, url string, fn scenarioFunc) {
loggedInUserScenarioWithRole(t, desc, "GET", url, url, models.ROLE_EDITOR, fn)
func loggedInUserScenario(t *testing.T, desc string, url string, routePattern string, fn scenarioFunc) {
loggedInUserScenarioWithRole(t, desc, "GET", url, routePattern, models.ROLE_EDITOR, fn)
}
func loggedInUserScenarioWithRole(t *testing.T, desc string, method string, url string, routePattern string, role models.RoleType, fn scenarioFunc) {

View File

@ -529,7 +529,10 @@ func (hs *HTTPServer) addGettingStartedPanelToHomeDashboard(c *models.ReqContext
// GetDashboardVersions returns all dashboard versions as JSON
func GetDashboardVersions(c *models.ReqContext) response.Response {
dashID := c.ParamsInt64(":dashboardId")
dashID, err := strconv.ParseInt(web.Params(c.Req)[":dashboardId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "dashboardId is invalid", err)
}
guardian := guardian.New(c.Req.Context(), dashID, c.OrgId, c.SignedInUser)
if canSave, err := guardian.CanSave(); err != nil || !canSave {
@ -568,7 +571,10 @@ func GetDashboardVersions(c *models.ReqContext) response.Response {
// GetDashboardVersion returns the dashboard version with the given ID.
func GetDashboardVersion(c *models.ReqContext) response.Response {
dashID := c.ParamsInt64(":dashboardId")
dashID, err := strconv.ParseInt(web.Params(c.Req)[":dashboardId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "dashboardId is invalid", err)
}
guardian := guardian.New(c.Req.Context(), dashID, c.OrgId, c.SignedInUser)
if canSave, err := guardian.CanSave(); err != nil || !canSave {
@ -660,7 +666,12 @@ func (hs *HTTPServer) RestoreDashboardVersion(c *models.ReqContext) response.Res
if err := web.Bind(c.Req, &apiCmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
dash, rsp := getDashboardHelper(c.Req.Context(), c.OrgId, c.ParamsInt64(":dashboardId"), "")
dashboardId, err := strconv.ParseInt(web.Params(c.Req)[":dashboardId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "dashboardId is invalid", err)
}
dash, rsp := getDashboardHelper(c.Req.Context(), c.OrgId, dashboardId, "")
if rsp != nil {
return rsp
}

View File

@ -3,6 +3,7 @@ package api
import (
"errors"
"net/http"
"strconv"
"time"
"github.com/grafana/grafana/pkg/api/dtos"
@ -13,7 +14,10 @@ import (
)
func (hs *HTTPServer) GetDashboardPermissionList(c *models.ReqContext) response.Response {
dashID := c.ParamsInt64(":dashboardId")
dashID, err := strconv.ParseInt(web.Params(c.Req)[":dashboardId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "dashboardId is invalid", err)
}
_, rsp := getDashboardHelper(c.Req.Context(), c.OrgId, dashID, "")
if rsp != nil {
@ -61,7 +65,10 @@ func (hs *HTTPServer) UpdateDashboardPermissions(c *models.ReqContext) response.
return response.Error(400, err.Error(), err)
}
dashID := c.ParamsInt64(":dashboardId")
dashID, err := strconv.ParseInt(web.Params(c.Req)[":dashboardId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "dashboardId is invalid", err)
}
_, rsp := getDashboardHelper(c.Req.Context(), c.OrgId, dashID, "")
if rsp != nil {

View File

@ -32,7 +32,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
}
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/1/permissions",
"/api/dashboards/id/:id/permissions", models.ROLE_EDITOR, func(sc *scenarioContext) {
"/api/dashboards/id/:dashboardId/permissions", models.ROLE_EDITOR, func(sc *scenarioContext) {
setUp()
callGetDashboardPermissions(sc, hs)
assert.Equal(t, 404, sc.resp.Code)
@ -47,7 +47,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
updateDashboardPermissionScenario(t, updatePermissionContext{
desc: "When calling POST on",
url: "/api/dashboards/id/1/permissions",
routePattern: "/api/dashboards/id/:id/permissions",
routePattern: "/api/dashboards/id/:dashboardId/permissions",
cmd: cmd,
fn: func(sc *scenarioContext) {
setUp()
@ -75,7 +75,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
}
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/1/permissions",
"/api/dashboards/id/:id/permissions", models.ROLE_EDITOR, func(sc *scenarioContext) {
"/api/dashboards/id/:dashboardId/permissions", models.ROLE_EDITOR, func(sc *scenarioContext) {
setUp()
callGetDashboardPermissions(sc, hs)
assert.Equal(t, 403, sc.resp.Code)
@ -90,7 +90,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
updateDashboardPermissionScenario(t, updatePermissionContext{
desc: "When calling POST on",
url: "/api/dashboards/id/1/permissions",
routePattern: "/api/dashboards/id/:id/permissions",
routePattern: "/api/dashboards/id/:dashboardId/permissions",
cmd: cmd,
fn: func(sc *scenarioContext) {
setUp()
@ -127,7 +127,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
}
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/1/permissions",
"/api/dashboards/id/:id/permissions", models.ROLE_ADMIN, func(sc *scenarioContext) {
"/api/dashboards/id/:dashboardId/permissions", models.ROLE_ADMIN, func(sc *scenarioContext) {
setUp()
callGetDashboardPermissions(sc, hs)
assert.Equal(t, 200, sc.resp.Code)
@ -150,7 +150,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
updateDashboardPermissionScenario(t, updatePermissionContext{
desc: "When calling POST on",
url: "/api/dashboards/id/1/permissions",
routePattern: "/api/dashboards/id/:id/permissions",
routePattern: "/api/dashboards/id/:dashboardId/permissions",
cmd: cmd,
fn: func(sc *scenarioContext) {
setUp()
@ -188,7 +188,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
updateDashboardPermissionScenario(t, updatePermissionContext{
desc: "When calling POST on",
url: "/api/dashboards/id/1/permissions",
routePattern: "/api/dashboards/id/:id/permissions",
routePattern: "/api/dashboards/id/:dashboardId/permissions",
cmd: cmd,
fn: func(sc *scenarioContext) {
setUp()
@ -229,7 +229,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
updateDashboardPermissionScenario(t, updatePermissionContext{
desc: "When calling POST on",
url: "/api/dashboards/id/1/permissions",
routePattern: "/api/dashboards/id/:id/permissions",
routePattern: "/api/dashboards/id/:dashboardId/permissions",
cmd: cmd,
fn: func(sc *scenarioContext) {
setUp()
@ -258,7 +258,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
updateDashboardPermissionScenario(t, updatePermissionContext{
desc: "When calling POST on",
url: "/api/dashboards/id/1/permissions",
routePattern: "/api/dashboards/id/:id/permissions",
routePattern: "/api/dashboards/id/:dashboardId/permissions",
cmd: cmd,
fn: func(sc *scenarioContext) {
callUpdateDashboardPermissions(t, sc)
@ -300,7 +300,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
updateDashboardPermissionScenario(t, updatePermissionContext{
desc: "When calling POST on",
url: "/api/dashboards/id/1/permissions",
routePattern: "/api/dashboards/id/:id/permissions",
routePattern: "/api/dashboards/id/:dashboardId/permissions",
cmd: cmd,
fn: func(sc *scenarioContext) {
setUp()
@ -344,7 +344,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
var resp []*models.DashboardAclInfoDTO
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/1/permissions",
"/api/dashboards/id/:id/permissions", models.ROLE_ADMIN, func(sc *scenarioContext) {
"/api/dashboards/id/:dashboardId/permissions", models.ROLE_ADMIN, func(sc *scenarioContext) {
setUp()
callGetDashboardPermissions(sc, hs)
assert.Equal(t, 200, sc.resp.Code)
@ -375,7 +375,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
updateDashboardPermissionScenario(t, updatePermissionContext{
desc: "When calling POST on",
url: "/api/dashboards/id/1/permissions",
routePattern: "/api/dashboards/id/:id/permissions",
routePattern: "/api/dashboards/id/:dashboardId/permissions",
cmd: cmd,
fn: func(sc *scenarioContext) {
setUp()

View File

@ -7,6 +7,7 @@ import (
"fmt"
"net/http"
"sort"
"strconv"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/api/datasource"
@ -82,8 +83,12 @@ func (hs *HTTPServer) getDataSourceAccessControlMetadata(c *models.ReqContext, d
}
func (hs *HTTPServer) GetDataSourceById(c *models.ReqContext) response.Response {
id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
query := models.GetDataSourceQuery{
Id: c.ParamsInt64(":id"),
Id: id,
OrgId: c.OrgId,
}
@ -111,7 +116,10 @@ func (hs *HTTPServer) GetDataSourceById(c *models.ReqContext) response.Response
}
func (hs *HTTPServer) DeleteDataSourceById(c *models.ReqContext) response.Response {
id := c.ParamsInt64(":id")
id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
if id <= 0 {
return response.Error(400, "Missing valid datasource id", nil)
@ -279,12 +287,16 @@ func (hs *HTTPServer) UpdateDataSource(c *models.ReqContext) response.Response {
}
datasourcesLogger.Debug("Received command to update data source", "url", cmd.Url)
cmd.OrgId = c.OrgId
cmd.Id = c.ParamsInt64(":id")
var err error
cmd.Id, err = strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
if resp := validateURL(cmd.Type, cmd.Url); resp != nil {
return resp
}
err := hs.fillWithSecureJSONData(c.Req.Context(), &cmd)
err = hs.fillWithSecureJSONData(c.Req.Context(), &cmd)
if err != nil {
return response.Error(500, "Failed to update datasource", err)
}
@ -410,7 +422,11 @@ func GetDataSourceIdByName(c *models.ReqContext) response.Response {
// /api/datasources/:id/resources/*
func (hs *HTTPServer) CallDatasourceResource(c *models.ReqContext) {
datasourceID := c.ParamsInt64(":id")
datasourceID, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
c.JsonApiErr(http.StatusBadRequest, "id is invalid", err)
return
}
ds, err := hs.DataSourceCache.GetDatasource(c.Req.Context(), datasourceID, c.SignedInUser, c.SkipCache)
if err != nil {
if errors.Is(err, models.ErrDataSourceAccessDenied) {
@ -465,7 +481,10 @@ func convertModelToDtos(ds *models.DataSource) dtos.DataSource {
// CheckDatasourceHealth sends a health check request to the plugin datasource
// /api/datasource/:id/health
func (hs *HTTPServer) CheckDatasourceHealth(c *models.ReqContext) response.Response {
datasourceID := c.ParamsInt64(":id")
datasourceID, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
ds, err := hs.DataSourceCache.GetDatasource(c.Req.Context(), datasourceID, c.SignedInUser, c.SkipCache)
if err != nil {

View File

@ -28,7 +28,7 @@ const (
)
func TestDataSourcesProxy_userLoggedIn(t *testing.T) {
loggedInUserScenario(t, "When calling GET on", "/api/datasources/", func(sc *scenarioContext) {
loggedInUserScenario(t, "When calling GET on", "/api/datasources/", "/api/datasources/", func(sc *scenarioContext) {
// Stubs the database query
bus.AddHandler("test", func(ctx context.Context, query *models.GetDataSourcesQuery) error {
assert.Equal(t, testOrgID, query.OrgId)
@ -61,7 +61,7 @@ func TestDataSourcesProxy_userLoggedIn(t *testing.T) {
})
loggedInUserScenario(t, "Should be able to save a data source when calling DELETE on non-existing",
"/api/datasources/name/12345", func(sc *scenarioContext) {
"/api/datasources/name/12345", "/api/datasources/name/:name", func(sc *scenarioContext) {
// handler func being tested
hs := &HTTPServer{
Bus: bus.GetBus(),

View File

@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"net/http"
"strconv"
"github.com/grafana/grafana/pkg/api/apierrors"
"github.com/grafana/grafana/pkg/api/dtos"
@ -51,7 +52,13 @@ func (hs *HTTPServer) GetFolderByUID(c *models.ReqContext) response.Response {
func (hs *HTTPServer) GetFolderByID(c *models.ReqContext) response.Response {
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
folder, err := s.GetFolderByID(c.Req.Context(), c.ParamsInt64(":id"))
id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
folder, err := s.GetFolderByID(c.Req.Context(), id)
if err != nil {
return apierrors.ToFolderErrorResponse(err)
}

View File

@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"net/http"
"strconv"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/bus"
@ -163,7 +164,10 @@ func (hs *HTTPServer) PostSyncUserWithLDAP(c *models.ReqContext) response.Respon
return response.Error(http.StatusBadRequest, "Failed to obtain the LDAP configuration. Please verify the configuration and try again", err)
}
userId := c.ParamsInt64(":id")
userId, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
query := models.GetUserByIdQuery{Id: userId}

View File

@ -639,7 +639,7 @@ func TestLDAP_AccessControl(t *testing.T) {
},
},
{
url: "/api/admin/ldap/sync/test",
url: "/api/admin/ldap/sync/1",
method: http.MethodPost,
desc: "PostSyncUserWithLDAP should return 200 for user without required permissions",
expectedCode: http.StatusOK,
@ -648,7 +648,7 @@ func TestLDAP_AccessControl(t *testing.T) {
},
},
{
url: "/api/admin/ldap/sync/test",
url: "/api/admin/ldap/sync/1",
method: http.MethodPost,
desc: "PostSyncUserWithLDAP should return 200 for user without required permissions",
expectedCode: http.StatusForbidden,

View File

@ -4,6 +4,7 @@ import (
"context"
"errors"
"net/http"
"strconv"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response"
@ -22,7 +23,11 @@ func GetCurrentOrg(c *models.ReqContext) response.Response {
// GET /api/orgs/:orgId
func GetOrgByID(c *models.ReqContext) response.Response {
return getOrgHelper(c.Req.Context(), c.ParamsInt64(":orgId"))
orgId, err := strconv.ParseInt(web.Params(c.Req)[":orgId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "orgId is invalid", err)
}
return getOrgHelper(c.Req.Context(), orgId)
}
// GET /api/orgs/name/:name
@ -120,7 +125,12 @@ func UpdateOrg(c *models.ReqContext) response.Response {
if err := web.Bind(c.Req, &form); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
return updateOrgHelper(c.Req.Context(), form, c.ParamsInt64(":orgId"))
orgId, err := strconv.ParseInt(web.Params(c.Req)[":orgId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "orgId is invalid", err)
}
return updateOrgHelper(c.Req.Context(), form, orgId)
}
func updateOrgHelper(ctx context.Context, form dtos.UpdateOrgForm, orgID int64) response.Response {
@ -150,7 +160,11 @@ func UpdateOrgAddress(c *models.ReqContext) response.Response {
if err := web.Bind(c.Req, &form); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
return updateOrgAddressHelper(c.Req.Context(), form, c.ParamsInt64(":orgId"))
orgId, err := strconv.ParseInt(web.Params(c.Req)[":orgId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "orgId is invalid", err)
}
return updateOrgAddressHelper(c.Req.Context(), form, orgId)
}
func updateOrgAddressHelper(ctx context.Context, form dtos.UpdateOrgAddressForm, orgID int64) response.Response {
@ -175,7 +189,10 @@ func updateOrgAddressHelper(ctx context.Context, form dtos.UpdateOrgAddressForm,
// DELETE /api/orgs/:orgId
func DeleteOrgByID(c *models.ReqContext) response.Response {
orgID := c.ParamsInt64(":orgId")
orgID, err := strconv.ParseInt(web.Params(c.Req)[":orgId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "orgId is invalid", err)
}
// before deleting an org, check if user does not belong to the current org
if c.OrgId == orgID {
return response.Error(400, "Can not delete org for current user", nil)

View File

@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"net/http"
"strconv"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response"
@ -30,7 +31,12 @@ func (hs *HTTPServer) AddOrgUser(c *models.ReqContext) response.Response {
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
cmd.OrgId = c.ParamsInt64(":orgId")
var err error
cmd.OrgId, err = strconv.ParseInt(web.Params(c.Req)[":orgId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "orgId is invalid", err)
}
return hs.addOrgUserHelper(c.Req.Context(), cmd)
}
@ -122,8 +128,13 @@ func (hs *HTTPServer) getUserAccessControlMetadata(c *models.ReqContext, resourc
// GET /api/orgs/:orgId/users
func (hs *HTTPServer) GetOrgUsers(c *models.ReqContext) response.Response {
orgId, err := strconv.ParseInt(web.Params(c.Req)[":orgId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "orgId is invalid", err)
}
result, err := hs.getOrgUsersHelper(c, &models.GetOrgUsersQuery{
OrgId: c.ParamsInt64(":orgId"),
OrgId: orgId,
Query: "",
Limit: 0,
User: c.SignedInUser,
@ -219,18 +230,29 @@ func (hs *HTTPServer) UpdateOrgUserForCurrentOrg(c *models.ReqContext) response.
return response.Error(http.StatusBadRequest, "bad request data", err)
}
cmd.OrgId = c.OrgId
cmd.UserId = c.ParamsInt64(":userId")
var err error
cmd.UserId, err = strconv.ParseInt(web.Params(c.Req)[":userId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "userId is invalid", err)
}
return hs.updateOrgUserHelper(c.Req.Context(), cmd)
}
// PATCH /api/orgs/:orgId/users/:userId
func (hs *HTTPServer) UpdateOrgUser(c *models.ReqContext) response.Response {
cmd := models.UpdateOrgUserCommand{}
var err error
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
cmd.OrgId = c.ParamsInt64(":orgId")
cmd.UserId = c.ParamsInt64(":userId")
cmd.OrgId, err = strconv.ParseInt(web.Params(c.Req)[":orgId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "orgId is invalid", err)
}
cmd.UserId, err = strconv.ParseInt(web.Params(c.Req)[":userId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "userId is invalid", err)
}
return hs.updateOrgUserHelper(c.Req.Context(), cmd)
}
@ -250,8 +272,13 @@ func (hs *HTTPServer) updateOrgUserHelper(ctx context.Context, cmd models.Update
// DELETE /api/org/users/:userId
func (hs *HTTPServer) RemoveOrgUserForCurrentOrg(c *models.ReqContext) response.Response {
userId, err := strconv.ParseInt(web.Params(c.Req)[":userId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "userId is invalid", err)
}
return hs.removeOrgUserHelper(c.Req.Context(), &models.RemoveOrgUserCommand{
UserId: c.ParamsInt64(":userId"),
UserId: userId,
OrgId: c.OrgId,
ShouldDeleteOrphanedUser: true,
})
@ -259,9 +286,17 @@ func (hs *HTTPServer) RemoveOrgUserForCurrentOrg(c *models.ReqContext) response.
// DELETE /api/orgs/:orgId/users/:userId
func (hs *HTTPServer) RemoveOrgUser(c *models.ReqContext) response.Response {
userId, err := strconv.ParseInt(web.Params(c.Req)[":userId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "userId is invalid", err)
}
orgId, err := strconv.ParseInt(web.Params(c.Req)[":orgId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "orgId is invalid", err)
}
return hs.removeOrgUserHelper(c.Req.Context(), &models.RemoveOrgUserCommand{
UserId: c.ParamsInt64(":userId"),
OrgId: c.ParamsInt64(":orgId"),
UserId: userId,
OrgId: orgId,
})
}

View File

@ -41,7 +41,7 @@ func TestOrgUsersAPIEndpoint_userLoggedIn(t *testing.T) {
sqlStore.Cfg = settings
hs.SQLStore = sqlStore
loggedInUserScenario(t, "When calling GET on", "api/org/users", func(sc *scenarioContext) {
loggedInUserScenario(t, "When calling GET on", "api/org/users", "api/org/users", func(sc *scenarioContext) {
setUpGetOrgUsersDB(t, sqlStore)
sc.handlerFunc = hs.GetOrgUsersForCurrentOrg
@ -55,7 +55,7 @@ func TestOrgUsersAPIEndpoint_userLoggedIn(t *testing.T) {
assert.Len(t, resp, 3)
})
loggedInUserScenario(t, "When calling GET on", "api/org/users/search", func(sc *scenarioContext) {
loggedInUserScenario(t, "When calling GET on", "api/org/users/search", "api/org/users/search", func(sc *scenarioContext) {
setUpGetOrgUsersDB(t, sqlStore)
sc.handlerFunc = hs.SearchOrgUsersWithPaging
@ -73,7 +73,7 @@ func TestOrgUsersAPIEndpoint_userLoggedIn(t *testing.T) {
assert.Equal(t, 1, resp.Page)
})
loggedInUserScenario(t, "When calling GET with page and limit query parameters on", "api/org/users/search", func(sc *scenarioContext) {
loggedInUserScenario(t, "When calling GET with page and limit query parameters on", "api/org/users/search", "api/org/users/search", func(sc *scenarioContext) {
setUpGetOrgUsersDB(t, sqlStore)
sc.handlerFunc = hs.SearchOrgUsersWithPaging
@ -98,7 +98,7 @@ func TestOrgUsersAPIEndpoint_userLoggedIn(t *testing.T) {
}
t.Cleanup(func() { settings.HiddenUsers = make(map[string]struct{}) })
loggedInUserScenario(t, "When calling GET on", "api/org/users", func(sc *scenarioContext) {
loggedInUserScenario(t, "When calling GET on", "api/org/users", "api/org/users", func(sc *scenarioContext) {
setUpGetOrgUsersDB(t, sqlStore)
sc.handlerFunc = hs.GetOrgUsersForCurrentOrg

View File

@ -3,6 +3,7 @@ package api
import (
"context"
"net/http"
"strconv"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/bus"
@ -11,9 +12,13 @@ import (
)
func ValidateOrgPlaylist(c *models.ReqContext) {
id := c.ParamsInt64(":id")
id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
c.JsonApiErr(http.StatusBadRequest, "id is invalid", nil)
return
}
query := models.GetPlaylistByIdQuery{Id: id}
err := bus.Dispatch(c.Req.Context(), &query)
err = bus.Dispatch(c.Req.Context(), &query)
if err != nil {
c.JsonApiErr(404, "Playlist not found", err)
@ -54,7 +59,10 @@ func SearchPlaylists(c *models.ReqContext) response.Response {
}
func GetPlaylist(c *models.ReqContext) response.Response {
id := c.ParamsInt64(":id")
id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
cmd := models.GetPlaylistByIdQuery{Id: id}
if err := bus.Dispatch(c.Req.Context(), &cmd); err != nil {
@ -107,7 +115,10 @@ func LoadPlaylistItems(ctx context.Context, id int64) ([]models.PlaylistItem, er
}
func GetPlaylistItems(c *models.ReqContext) response.Response {
id := c.ParamsInt64(":id")
id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
playlistDTOs, err := LoadPlaylistItemDTOs(c.Req.Context(), id)
@ -119,7 +130,10 @@ func GetPlaylistItems(c *models.ReqContext) response.Response {
}
func GetPlaylistDashboards(c *models.ReqContext) response.Response {
playlistID := c.ParamsInt64(":id")
playlistID, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
playlists, err := LoadPlaylistDashboards(c.Req.Context(), c.OrgId, c.SignedInUser, playlistID)
if err != nil {
@ -130,7 +144,10 @@ func GetPlaylistDashboards(c *models.ReqContext) response.Response {
}
func DeletePlaylist(c *models.ReqContext) response.Response {
id := c.ParamsInt64(":id")
id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
cmd := models.DeletePlaylistCommand{Id: id, OrgId: c.OrgId}
if err := bus.Dispatch(c.Req.Context(), &cmd); err != nil {
@ -160,7 +177,11 @@ func UpdatePlaylist(c *models.ReqContext) response.Response {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
cmd.OrgId = c.OrgId
cmd.Id = c.ParamsInt64(":id")
var err error
cmd.Id, err = strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
if err := bus.Dispatch(c.Req.Context(), &cmd); err != nil {
return response.Error(500, "Failed to save playlist", err)

View File

@ -2,6 +2,7 @@ package api
import (
"net/http"
"strconv"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/bus"
@ -15,7 +16,11 @@ func (hs *HTTPServer) GetCurrentOrgQuotas(c *models.ReqContext) response.Respons
}
func (hs *HTTPServer) GetOrgQuotas(c *models.ReqContext) response.Response {
return hs.getOrgQuotasHelper(c, c.ParamsInt64(":orgId"))
orgId, err := strconv.ParseInt(web.Params(c.Req)[":orgId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "orgId is invalid", err)
}
return hs.getOrgQuotasHelper(c, orgId)
}
func (hs *HTTPServer) getOrgQuotasHelper(c *models.ReqContext, orgID int64) response.Response {
@ -33,13 +38,17 @@ func (hs *HTTPServer) getOrgQuotasHelper(c *models.ReqContext, orgID int64) resp
func (hs *HTTPServer) UpdateOrgQuota(c *models.ReqContext) response.Response {
cmd := models.UpdateOrgQuotaCmd{}
var err error
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
if !hs.Cfg.Quota.Enabled {
return response.Error(404, "Quotas not enabled", nil)
}
cmd.OrgId = c.ParamsInt64(":orgId")
cmd.OrgId, err = strconv.ParseInt(web.Params(c.Req)[":orgId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "orgId is invalid", err)
}
cmd.Target = web.Params(c.Req)[":target"]
if _, ok := hs.Cfg.Quota.Org.ToMap()[cmd.Target]; !ok {
@ -56,7 +65,13 @@ func GetUserQuotas(c *models.ReqContext) response.Response {
if !setting.Quota.Enabled {
return response.Error(404, "Quotas not enabled", nil)
}
query := models.GetUserQuotasQuery{UserId: c.ParamsInt64(":id")}
id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
query := models.GetUserQuotasQuery{UserId: id}
if err := bus.Dispatch(c.Req.Context(), &query); err != nil {
return response.Error(500, "Failed to get org quotas", err)
@ -67,13 +82,17 @@ func GetUserQuotas(c *models.ReqContext) response.Response {
func UpdateUserQuota(c *models.ReqContext) response.Response {
cmd := models.UpdateUserQuotaCmd{}
var err error
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
if !setting.Quota.Enabled {
return response.Error(404, "Quotas not enabled", nil)
}
cmd.UserId = c.ParamsInt64(":id")
cmd.UserId, err = strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
cmd.Target = web.Params(c.Req)[":target"]
if _, ok := setting.Quota.User.ToMap()[cmd.Target]; !ok {

View File

@ -1,13 +1,21 @@
package api
import (
"net/http"
"strconv"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/web"
)
func StarDashboard(c *models.ReqContext) response.Response {
cmd := models.StarDashboardCommand{UserId: c.UserId, DashboardId: c.ParamsInt64(":id")}
id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
cmd := models.StarDashboardCommand{UserId: c.UserId, DashboardId: id}
if cmd.DashboardId <= 0 {
return response.Error(400, "Missing dashboard id", nil)
@ -21,7 +29,11 @@ func StarDashboard(c *models.ReqContext) response.Response {
}
func UnstarDashboard(c *models.ReqContext) response.Response {
cmd := models.UnstarDashboardCommand{UserId: c.UserId, DashboardId: c.ParamsInt64(":id")}
id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
cmd := models.UnstarDashboardCommand{UserId: c.UserId, DashboardId: id}
if cmd.DashboardId <= 0 {
return response.Error(400, "Missing dashboard id", nil)

View File

@ -3,6 +3,7 @@ package api
import (
"errors"
"net/http"
"strconv"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response"
@ -55,11 +56,15 @@ func (hs *HTTPServer) CreateTeam(c *models.ReqContext) response.Response {
// PUT /api/teams/:teamId
func (hs *HTTPServer) UpdateTeam(c *models.ReqContext) response.Response {
cmd := models.UpdateTeamCommand{}
var err error
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
cmd.OrgId = c.OrgId
cmd.Id = c.ParamsInt64(":teamId")
cmd.Id, err = strconv.ParseInt(web.Params(c.Req)[":teamId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "teamId is invalid", err)
}
if err := hs.teamGuardian.CanAdmin(c.Req.Context(), cmd.OrgId, cmd.Id, c.SignedInUser); err != nil {
return response.Error(403, "Not allowed to update team", err)
@ -78,7 +83,10 @@ func (hs *HTTPServer) UpdateTeam(c *models.ReqContext) response.Response {
// DELETE /api/teams/:teamId
func (hs *HTTPServer) DeleteTeamByID(c *models.ReqContext) response.Response {
orgId := c.OrgId
teamId := c.ParamsInt64(":teamId")
teamId, err := strconv.ParseInt(web.Params(c.Req)[":teamId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "teamId is invalid", err)
}
user := c.SignedInUser
if err := hs.teamGuardian.CanAdmin(c.Req.Context(), orgId, teamId, user); err != nil {
@ -137,9 +145,13 @@ func (hs *HTTPServer) SearchTeams(c *models.ReqContext) response.Response {
// GET /api/teams/:teamId
func (hs *HTTPServer) GetTeamByID(c *models.ReqContext) response.Response {
teamId, err := strconv.ParseInt(web.Params(c.Req)[":teamId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "teamId is invalid", err)
}
query := models.GetTeamByIdQuery{
OrgId: c.OrgId,
Id: c.ParamsInt64(":teamId"),
Id: teamId,
SignedInUser: c.SignedInUser,
HiddenUsers: hs.Cfg.HiddenUsers,
}
@ -158,7 +170,10 @@ func (hs *HTTPServer) GetTeamByID(c *models.ReqContext) response.Response {
// GET /api/teams/:teamId/preferences
func (hs *HTTPServer) GetTeamPreferences(c *models.ReqContext) response.Response {
teamId := c.ParamsInt64(":teamId")
teamId, err := strconv.ParseInt(web.Params(c.Req)[":teamId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "teamId is invalid", err)
}
orgId := c.OrgId
if err := hs.teamGuardian.CanAdmin(c.Req.Context(), orgId, teamId, c.SignedInUser); err != nil {
@ -174,7 +189,10 @@ func (hs *HTTPServer) UpdateTeamPreferences(c *models.ReqContext) response.Respo
if err := web.Bind(c.Req, &dtoCmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
teamId := c.ParamsInt64(":teamId")
teamId, err := strconv.ParseInt(web.Params(c.Req)[":teamId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "teamId is invalid", err)
}
orgId := c.OrgId
if err := hs.teamGuardian.CanAdmin(c.Req.Context(), orgId, teamId, c.SignedInUser); err != nil {

View File

@ -3,6 +3,7 @@ package api
import (
"errors"
"net/http"
"strconv"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response"
@ -15,7 +16,12 @@ import (
// GET /api/teams/:teamId/members
func (hs *HTTPServer) GetTeamMembers(c *models.ReqContext) response.Response {
query := models.GetTeamMembersQuery{OrgId: c.OrgId, TeamId: c.ParamsInt64(":teamId")}
teamId, err := strconv.ParseInt(web.Params(c.Req)[":teamId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "teamId is invalid", err)
}
query := models.GetTeamMembersQuery{OrgId: c.OrgId, TeamId: teamId}
if err := bus.Dispatch(c.Req.Context(), &query); err != nil {
return response.Error(500, "Failed to get Team Members", err)
@ -44,17 +50,21 @@ func (hs *HTTPServer) GetTeamMembers(c *models.ReqContext) response.Response {
// POST /api/teams/:teamId/members
func (hs *HTTPServer) AddTeamMember(c *models.ReqContext) response.Response {
cmd := models.AddTeamMemberCommand{}
var err error
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
cmd.OrgId = c.OrgId
cmd.TeamId = c.ParamsInt64(":teamId")
cmd.TeamId, err = strconv.ParseInt(web.Params(c.Req)[":teamId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "teamId is invalid", err)
}
if err := hs.teamGuardian.CanAdmin(c.Req.Context(), cmd.OrgId, cmd.TeamId, c.SignedInUser); err != nil {
return response.Error(403, "Not allowed to add team member", err)
}
err := addTeamMember(hs.SQLStore, cmd.UserId, cmd.OrgId, cmd.TeamId, cmd.External, cmd.Permission)
err = addTeamMember(hs.SQLStore, cmd.UserId, cmd.OrgId, cmd.TeamId, cmd.External, cmd.Permission)
if err != nil {
if errors.Is(err, models.ErrTeamNotFound) {
return response.Error(404, "Team not found", nil)
@ -78,7 +88,10 @@ func (hs *HTTPServer) UpdateTeamMember(c *models.ReqContext) response.Response {
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
teamId := c.ParamsInt64(":teamId")
teamId, err := strconv.ParseInt(web.Params(c.Req)[":teamId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "teamId is invalid", err)
}
orgId := c.OrgId
if err := hs.teamGuardian.CanAdmin(c.Req.Context(), orgId, teamId, c.SignedInUser); err != nil {
@ -90,7 +103,10 @@ func (hs *HTTPServer) UpdateTeamMember(c *models.ReqContext) response.Response {
}
cmd.TeamId = teamId
cmd.UserId = c.ParamsInt64(":userId")
cmd.UserId, err = strconv.ParseInt(web.Params(c.Req)[":userId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "userId is invalid", err)
}
cmd.OrgId = orgId
if err := hs.Bus.Dispatch(c.Req.Context(), &cmd); err != nil {
@ -105,8 +121,14 @@ func (hs *HTTPServer) UpdateTeamMember(c *models.ReqContext) response.Response {
// DELETE /api/teams/:teamId/members/:userId
func (hs *HTTPServer) RemoveTeamMember(c *models.ReqContext) response.Response {
orgId := c.OrgId
teamId := c.ParamsInt64(":teamId")
userId := c.ParamsInt64(":userId")
teamId, err := strconv.ParseInt(web.Params(c.Req)[":teamId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "teamId is invalid", err)
}
userId, err := strconv.ParseInt(web.Params(c.Req)[":userId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "userId is invalid", err)
}
if err := hs.teamGuardian.CanAdmin(c.Req.Context(), orgId, teamId, c.SignedInUser); err != nil {
return response.Error(403, "Not allowed to remove team member", err)

View File

@ -44,7 +44,7 @@ func TestTeamAPIEndpoint(t *testing.T) {
Cfg: setting.NewCfg(),
}
loggedInUserScenario(t, "When calling GET on", "/api/teams/search", func(sc *scenarioContext) {
loggedInUserScenario(t, "When calling GET on", "/api/teams/search", "/api/teams/search", func(sc *scenarioContext) {
var sentLimit int
var sendPage int
bus.AddHandler("test", func(ctx context.Context, query *models.SearchTeamsQuery) error {
@ -69,7 +69,7 @@ func TestTeamAPIEndpoint(t *testing.T) {
assert.Equal(t, 2, len(respJSON.Get("teams").MustArray()))
})
loggedInUserScenario(t, "When calling GET on", "/api/teams/search", func(sc *scenarioContext) {
loggedInUserScenario(t, "When calling GET on", "/api/teams/search", "/api/teams/search", func(sc *scenarioContext) {
var sentLimit int
var sendPage int
bus.AddHandler("test", func(ctx context.Context, query *models.SearchTeamsQuery) error {

View File

@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"net/http"
"strconv"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response"
@ -23,7 +24,11 @@ func (hs *HTTPServer) GetSignedInUser(c *models.ReqContext) response.Response {
// GET /api/users/:id
func (hs *HTTPServer) GetUserByID(c *models.ReqContext) response.Response {
return hs.getUserUserProfile(c, c.ParamsInt64(":id"))
id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
return hs.getUserUserProfile(c, id)
}
func (hs *HTTPServer) getUserUserProfile(c *models.ReqContext, userID int64) response.Response {
@ -116,17 +121,27 @@ func UpdateSignedInUser(c *models.ReqContext) response.Response {
// POST /api/users/:id
func UpdateUser(c *models.ReqContext) response.Response {
cmd := models.UpdateUserCommand{}
var err error
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
cmd.UserId = c.ParamsInt64(":id")
cmd.UserId, err = strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
return handleUpdateUser(c.Req.Context(), cmd)
}
// POST /api/users/:id/using/:orgId
func UpdateUserActiveOrg(c *models.ReqContext) response.Response {
userID := c.ParamsInt64(":id")
orgID := c.ParamsInt64(":orgId")
userID, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
orgID, err := strconv.ParseInt(web.Params(c.Req)[":orgId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "orgId is invalid", err)
}
if !validateUsingOrg(c.Req.Context(), userID, orgID) {
return response.Error(401, "Not a valid organization", nil)
@ -168,7 +183,11 @@ func GetSignedInUserTeamList(c *models.ReqContext) response.Response {
// GET /api/users/:id/teams
func GetUserTeams(c *models.ReqContext) response.Response {
return getUserTeamList(c.Req.Context(), c.OrgId, c.ParamsInt64(":id"))
id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
return getUserTeamList(c.Req.Context(), c.OrgId, id)
}
func getUserTeamList(ctx context.Context, orgID int64, userID int64) response.Response {
@ -186,7 +205,11 @@ func getUserTeamList(ctx context.Context, orgID int64, userID int64) response.Re
// GET /api/users/:id/orgs
func GetUserOrgList(c *models.ReqContext) response.Response {
return getUserOrgList(c.Req.Context(), c.ParamsInt64(":id"))
id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
return getUserOrgList(c.Req.Context(), id)
}
func getUserOrgList(ctx context.Context, userID int64) response.Response {
@ -219,7 +242,10 @@ func validateUsingOrg(ctx context.Context, userID int64, orgID int64) bool {
// POST /api/user/using/:id
func UserSetUsingOrg(c *models.ReqContext) response.Response {
orgID := c.ParamsInt64(":id")
orgID, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
if !validateUsingOrg(c.Req.Context(), c.UserId, orgID) {
return response.Error(401, "Not a valid organization", nil)
@ -236,7 +262,11 @@ func UserSetUsingOrg(c *models.ReqContext) response.Response {
// GET /profile/switch-org/:id
func (hs *HTTPServer) ChangeActiveOrgAndRedirectToHome(c *models.ReqContext) {
orgID := c.ParamsInt64(":id")
orgID, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
c.JsonApiErr(http.StatusBadRequest, "id is invalid", err)
return
}
if !validateUsingOrg(c.Req.Context(), c.UserId, orgID) {
hs.NotFoundHandler(c)
@ -298,7 +328,10 @@ func redirectToChangePassword(c *models.ReqContext) {
}
func SetHelpFlag(c *models.ReqContext) response.Response {
flag := c.ParamsInt64(":id")
flag, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
bitmask := &c.HelpFlags1
bitmask.AddFlag(models.HelpFlags1(flag))

View File

@ -36,7 +36,7 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
TotalCount: 2,
}
loggedInUserScenario(t, "When calling GET on", "api/users/:id", func(sc *scenarioContext) {
loggedInUserScenario(t, "When calling GET on", "api/users/1", "api/users/:id", func(sc *scenarioContext) {
fakeNow := time.Date(2019, 2, 11, 17, 30, 40, 0, time.UTC)
bus.AddHandler("test", func(ctx context.Context, query *models.GetUserProfileQuery) error {
query.Result = models.UserProfileDTO{
@ -63,7 +63,7 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
sc.handlerFunc = hs.GetUserByID
avatarUrl := dtos.GetGravatarUrl("daniel@grafana.com")
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
sc.fakeReqWithParams("GET", sc.url, map[string]string{"id": "1"}).exec()
expected := fmt.Sprintf(`
{
@ -89,7 +89,7 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
require.JSONEq(t, expected, sc.resp.Body.String())
})
loggedInUserScenario(t, "When calling GET on", "/api/users/lookup", func(sc *scenarioContext) {
loggedInUserScenario(t, "When calling GET on", "/api/users/lookup", "/api/users/lookup", func(sc *scenarioContext) {
fakeNow := time.Date(2019, 2, 11, 17, 30, 40, 0, time.UTC)
bus.AddHandler("test", func(ctx context.Context, query *models.GetUserByLoginQuery) error {
require.Equal(t, "danlee", query.LoginOrEmail)
@ -135,7 +135,7 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
require.JSONEq(t, expected, sc.resp.Body.String())
})
loggedInUserScenario(t, "When calling GET on", "/api/users", func(sc *scenarioContext) {
loggedInUserScenario(t, "When calling GET on", "/api/users", "/api/users", func(sc *scenarioContext) {
var sentLimit int
var sendPage int
bus.AddHandler("test", func(ctx context.Context, query *models.SearchUsersQuery) error {
@ -159,7 +159,7 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
assert.Equal(t, 2, len(respJSON.MustArray()))
})
loggedInUserScenario(t, "When calling GET with page and limit querystring parameters on", "/api/users", func(sc *scenarioContext) {
loggedInUserScenario(t, "When calling GET with page and limit querystring parameters on", "/api/users", "/api/users", func(sc *scenarioContext) {
var sentLimit int
var sendPage int
bus.AddHandler("test", func(ctx context.Context, query *models.SearchUsersQuery) error {
@ -179,7 +179,7 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
assert.Equal(t, 2, sendPage)
})
loggedInUserScenario(t, "When calling GET on", "/api/users/search", func(sc *scenarioContext) {
loggedInUserScenario(t, "When calling GET on", "/api/users/search", "/api/users/search", func(sc *scenarioContext) {
var sentLimit int
var sendPage int
bus.AddHandler("test", func(ctx context.Context, query *models.SearchUsersQuery) error {
@ -205,7 +205,7 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
assert.Equal(t, 2, len(respJSON.Get("users").MustArray()))
})
loggedInUserScenario(t, "When calling GET with page and perpage querystring parameters on", "/api/users/search", func(sc *scenarioContext) {
loggedInUserScenario(t, "When calling GET with page and perpage querystring parameters on", "/api/users/search", "/api/users/search", func(sc *scenarioContext) {
var sentLimit int
var sendPage int
bus.AddHandler("test", func(ctx context.Context, query *models.SearchUsersQuery) error {

View File

@ -3,6 +3,7 @@ package middleware
import (
"fmt"
"net/http"
"strconv"
"time"
"github.com/grafana/grafana/pkg/models"
@ -125,9 +126,10 @@ func AuthorizeInOrgMiddleware(ac accesscontrol.AccessControl, db *sqlstore.SQLSt
}
func UseOrgFromContextParams(c *models.ReqContext) (int64, error) {
orgID := c.ParamsInt64(":orgId")
orgID, err := strconv.ParseInt(web.Params(c.Req)[":orgId"], 10, 64)
// Special case of macaron handling invalid params
if orgID == 0 {
if orgID == 0 || err != nil {
return 0, models.ErrOrgNotFound
}

View File

@ -3,6 +3,7 @@ package resourcepermissions
import (
"fmt"
"net/http"
"strconv"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response"
@ -119,7 +120,10 @@ type setPermissionCommand struct {
}
func (a *api) setUserPermission(c *models.ReqContext) response.Response {
userID := c.ParamsInt64(":userID")
userID, err := strconv.ParseInt(web.Params(c.Req)[":userID"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "userID is invalid", err)
}
resourceID := web.Params(c.Req)[":resourceID"]
var cmd setPermissionCommand
@ -127,7 +131,7 @@ func (a *api) setUserPermission(c *models.ReqContext) response.Response {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
_, err := a.service.SetUserPermission(c.Req.Context(), c.OrgId, userID, resourceID, a.service.MapPermission(cmd.Permission))
_, err = a.service.SetUserPermission(c.Req.Context(), c.OrgId, userID, resourceID, a.service.MapPermission(cmd.Permission))
if err != nil {
return response.Error(http.StatusBadRequest, "failed to set user permission", err)
}
@ -136,7 +140,10 @@ func (a *api) setUserPermission(c *models.ReqContext) response.Response {
}
func (a *api) setTeamPermission(c *models.ReqContext) response.Response {
teamID := c.ParamsInt64(":teamID")
teamID, err := strconv.ParseInt(web.Params(c.Req)[":teamID"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "teamID is invalid", err)
}
resourceID := web.Params(c.Req)[":resourceID"]
var cmd setPermissionCommand
@ -144,7 +151,7 @@ func (a *api) setTeamPermission(c *models.ReqContext) response.Response {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
_, err := a.service.SetTeamPermission(c.Req.Context(), c.OrgId, teamID, resourceID, a.service.MapPermission(cmd.Permission))
_, err = a.service.SetTeamPermission(c.Req.Context(), c.OrgId, teamID, resourceID, a.service.MapPermission(cmd.Permission))
if err != nil {
return response.Error(http.StatusBadRequest, "failed to set team permission", err)
}

View File

@ -5,6 +5,7 @@ import (
"fmt"
"net/http"
"regexp"
"strconv"
"github.com/grafana/grafana/pkg/api/datasource"
"github.com/grafana/grafana/pkg/api/pluginproxy"
@ -15,6 +16,7 @@ import (
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/oauthtoken"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
)
func ProvideService(dataSourceCache datasources.CacheService, plugReqValidator models.PluginRequestValidator,
@ -42,7 +44,12 @@ type DataSourceProxyService struct {
}
func (p *DataSourceProxyService) ProxyDataSourceRequest(c *models.ReqContext) {
p.ProxyDatasourceRequestWithID(c, c.ParamsInt64(":id"))
id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
c.JsonApiErr(http.StatusBadRequest, "id is invalid", err)
return
}
p.ProxyDatasourceRequestWithID(c, id)
}
func (p *DataSourceProxyService) ProxyDatasourceRequestWithID(c *models.ReqContext, dsID int64) {

View File

@ -7,6 +7,7 @@ import (
"fmt"
"io"
"net/http"
"strconv"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/infra/log"
@ -59,7 +60,12 @@ func (am *LotexAM) withAMReq(
extractor func(*response.NormalResponse) (interface{}, error),
headers map[string]string,
) response.Response {
ds, err := am.DataProxy.DataSourceCache.GetDatasource(ctx.Req.Context(), ctx.ParamsInt64(":Recipient"), ctx.SignedInUser, ctx.SkipCache)
recipient, err := strconv.ParseInt(web.Params(ctx.Req)[":Recipient"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "Recipient is invalid", err)
}
ds, err := am.DataProxy.DataSourceCache.GetDatasource(ctx.Req.Context(), recipient, ctx.SignedInUser, ctx.SkipCache)
if err != nil {
if errors.Is(err, models.ErrDataSourceAccessDenied) {
return ErrResp(http.StatusForbidden, err, "Access denied to datasource")

View File

@ -3,11 +3,13 @@ package api
import (
"fmt"
"net/http"
"strconv"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
"github.com/grafana/grafana/pkg/web"
)
type promEndpoints struct {
@ -76,7 +78,12 @@ func (p *LotexProm) RouteGetRuleStatuses(ctx *models.ReqContext) response.Respon
}
func (p *LotexProm) getEndpoints(ctx *models.ReqContext) (*promEndpoints, error) {
ds, err := p.DataProxy.DataSourceCache.GetDatasource(ctx.Req.Context(), ctx.ParamsInt64(":Recipient"), ctx.SignedInUser, ctx.SkipCache)
recipient, err := strconv.ParseInt(web.Params(ctx.Req)[":Recipient"], 10, 64)
if err != nil {
return nil, fmt.Errorf("recipient is invalid")
}
ds, err := p.DataProxy.DataSourceCache.GetDatasource(ctx.Req.Context(), recipient, ctx.SignedInUser, ctx.SkipCache)
if err != nil {
return nil, err
}

View File

@ -5,6 +5,7 @@ import (
"fmt"
"net/http"
"net/url"
"strconv"
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
"github.com/grafana/grafana/pkg/web"
@ -152,7 +153,12 @@ func (r *LotexRuler) RoutePostNameRulesConfig(ctx *models.ReqContext, conf apimo
}
func (r *LotexRuler) validateAndGetPrefix(ctx *models.ReqContext) (string, error) {
ds, err := r.DataProxy.DataSourceCache.GetDatasource(ctx.Req.Context(), ctx.ParamsInt64(":Recipient"), ctx.SignedInUser, ctx.SkipCache)
recipient, err := strconv.ParseInt(web.Params(ctx.Req)[":Recipient"], 10, 64)
if err != nil {
return "", fmt.Errorf("recipient is invalid")
}
ds, err := r.DataProxy.DataSourceCache.GetDatasource(ctx.Req.Context(), recipient, ctx.SignedInUser, ctx.SkipCache)
if err != nil {
return "", err
}

View File

@ -105,7 +105,13 @@ func (p *AlertingProxy) withReq(
}
newCtx, resp := replacedResponseWriter(ctx)
newCtx.Req = req
p.DataProxy.ProxyDatasourceRequestWithID(newCtx, ctx.ParamsInt64(":Recipient"))
recipient, err := strconv.ParseInt(web.Params(ctx.Req)[":Recipient"], 10, 64)
if err != nil {
return ErrResp(http.StatusBadRequest, err, "Recipient is invalid")
}
p.DataProxy.ProxyDatasourceRequestWithID(newCtx, recipient)
status := resp.Status()
if status >= 400 {

View File

@ -3,6 +3,7 @@ package api
import (
"errors"
"net/http"
"strconv"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/api/routing"
@ -69,8 +70,11 @@ func (api *ServiceAccountsAPI) CreateServiceAccount(c *models.ReqContext) respon
}
func (api *ServiceAccountsAPI) DeleteServiceAccount(ctx *models.ReqContext) response.Response {
scopeID := ctx.ParamsInt64(":serviceAccountId")
err := api.service.DeleteServiceAccount(ctx.Req.Context(), ctx.OrgId, scopeID)
scopeID, err := strconv.ParseInt(web.Params(ctx.Req)[":serviceAccountId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "serviceAccountId is invalid", err)
}
err = api.service.DeleteServiceAccount(ctx.Req.Context(), ctx.OrgId, scopeID)
if err != nil {
return response.Error(http.StatusInternalServerError, "Service account deletion error", err)
}

View File

@ -179,13 +179,6 @@ func (ctx *Context) QueryInt64(name string) int64 {
return n
}
// ParamsInt64 returns params result in int64 type.
// e.g. ctx.ParamsInt64(":uid")
func (ctx *Context) ParamsInt64(name string) int64 {
n, _ := strconv.ParseInt(Params(ctx.Req)[name], 10, 64)
return n
}
// GetCookie returns given cookie value from request header.
func (ctx *Context) GetCookie(name string) string {
cookie, err := ctx.Req.Cookie(name)