Merge remote-tracking branch 'origin/main' into grafana-git-ui-sync

This commit is contained in:
Ryan McKinley committed 2025-03-10 10:03:17 +03:00
commit a8ee76264b
182 files changed
+3755 -977

No files matched your search

+4 -7
View File
@@ -85,6 +85,7 @@ func dashboardGuardianResponse(err error) response.Response {
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 406: notAcceptableError
// 500: internalServerError
//
//nolint:gocyclo
@@ -99,14 +100,10 @@ func (hs *HTTPServer) GetDashboard(c *contextmodel.ReqContext) response.Response
return rsp
}
// V2 values should be read from the k8s API
// v2 is not supported in /api
if strings.HasPrefix(dash.APIVersion, "v2") {
root := hs.Cfg.AppSubURL
if !strings.HasSuffix(root, "/") {
root += "/"
}
url := fmt.Sprintf("%sapis/dashboard.grafana.app/%s/namespaces/%s/dashboards/%s", root, dash.APIVersion, hs.namespacer(c.OrgID), dash.UID)
return response.Redirect(url)
url := fmt.Sprintf("/apis/dashboard.grafana.app/%s/namespaces/%s/dashboards/%s", dash.APIVersion, hs.namespacer(c.SignedInUser.GetOrgID()), dash.UID)
return response.Error(http.StatusNotAcceptable, "dashboard api version not supported, use "+url+" instead", nil)
}
var (
+41
View File
@@ -6,6 +6,7 @@ import (
"fmt"
"net/http"
"os"
"strconv"
"testing"
"time"
@@ -694,6 +695,46 @@ func TestDashboardAPIEndpoint(t *testing.T) {
assert.Equal(t, false, dash.Meta.Provisioned)
}, mockSQLStore)
})
t.Run("v2 dashboards should not be returned in api", func(t *testing.T) {
mockSQLStore := dbtest.NewFakeDB()
dashboardService := dashboards.NewFakeDashboardService(t)
dataValue, err := simplejson.NewJson([]byte(`{"id": 1, "apiVersion": "v2"}`))
require.NoError(t, err)
qResult := &dashboards.Dashboard{
ID: 1,
UID: "dash",
OrgID: 1,
APIVersion: "v2",
Data: dataValue,
}
dashboardService.On("GetDashboard", mock.Anything, mock.AnythingOfType("*dashboards.GetDashboardQuery")).Return(qResult, nil)
guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{CanViewValue: true})
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/dash", "/api/dashboards/uid/:uid", org.RoleEditor, func(sc *scenarioContext) {
hs := &HTTPServer{
Cfg: setting.NewCfg(),
LibraryPanelService: &mockLibraryPanelService{},
LibraryElementService: &libraryelementsfake.LibraryElementService{},
SQLStore: mockSQLStore,
AccessControl: accesscontrolmock.New(),
DashboardService: dashboardService,
Features: featuremgmt.WithFeatures(),
starService: startest.NewStarServiceFake(),
tracer: tracing.InitializeTracerForTest(),
dashboardProvisioningService: mockDashboardProvisioningService{},
folderService: foldertest.NewFakeService(),
log: log.New("test"),
namespacer: func(orgID int64) string { return strconv.FormatInt(orgID, 10) },
}
hs.callGetDashboard(sc)
assert.Equal(t, http.StatusNotAcceptable, sc.resp.Code)
result := sc.ToJSON()
assert.Equal(t, "dashboard api version not supported, use /apis/dashboard.grafana.app/v2/namespaces/1/dashboards/dash instead", result.Get("message").MustString())
}, mockSQLStore)
})
}
func TestDashboardVersionsAPIEndpoint(t *testing.T) {
+5
View File
@@ -52,6 +52,11 @@ type NotFoundError GenericError
// swagger:response badRequestError
type BadRequestError GenericError
// NotAcceptableError is returned when the server cannot produce a response matching the accepted formats.
//
// swagger:response notAcceptableError
type NotAcceptableError GenericError
// ConflictError
//
// swagger:response conflictError
+12 -10
View File
@@ -149,7 +149,7 @@ func (hs *HTTPServer) UpdateSignedInUser(c *contextmodel.ReqContext) response.Re
cmd.Email = strings.TrimSpace(cmd.Email)
cmd.Login = strings.TrimSpace(cmd.Login)
userID, errResponse := getUserID(c)
userID, errResponse := hs.getUserID(c)
if errResponse != nil {
return errResponse
}
@@ -349,7 +349,7 @@ func (hs *HTTPServer) UpdateUserEmail(c *contextmodel.ReqContext) response.Respo
// 403: forbiddenError
// 500: internalServerError
func (hs *HTTPServer) GetSignedInUserOrgList(c *contextmodel.ReqContext) response.Response {
userID, errResponse := getUserID(c)
userID, errResponse := hs.getUserID(c)
if errResponse != nil {
return errResponse
}
@@ -369,7 +369,7 @@ func (hs *HTTPServer) GetSignedInUserOrgList(c *contextmodel.ReqContext) respons
// 403: forbiddenError
// 500: internalServerError
func (hs *HTTPServer) GetSignedInUserTeamList(c *contextmodel.ReqContext) response.Response {
userID, errResponse := getUserID(c)
userID, errResponse := hs.getUserID(c)
if errResponse != nil {
return errResponse
}
@@ -479,7 +479,7 @@ func (hs *HTTPServer) UserSetUsingOrg(c *contextmodel.ReqContext) response.Respo
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
userID, errResponse := getUserID(c)
userID, errResponse := hs.getUserID(c)
if errResponse != nil {
return errResponse
}
@@ -504,7 +504,8 @@ func (hs *HTTPServer) ChangeActiveOrgAndRedirectToHome(c *contextmodel.ReqContex
}
if !c.SignedInUser.IsIdentityType(claims.TypeUser) {
c.JsonApiErr(http.StatusForbidden, "Endpoint only available for users", nil)
hs.log.Debug("Requested endpoint only available to users")
c.JsonApiErr(http.StatusNotModified, "Endpoint only available for users", nil)
return
}
@@ -548,7 +549,7 @@ func (hs *HTTPServer) ChangeUserPassword(c *contextmodel.ReqContext) response.Re
return response.Error(http.StatusBadRequest, "bad request data", err)
}
userID, errResponse := getUserID(c)
userID, errResponse := hs.getUserID(c)
if errResponse != nil {
return errResponse
}
@@ -584,7 +585,7 @@ func (hs *HTTPServer) SetHelpFlag(c *contextmodel.ReqContext) response.Response
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
userID, errResponse := getUserID(c)
userID, errResponse := hs.getUserID(c)
if errResponse != nil {
return errResponse
}
@@ -614,7 +615,7 @@ func (hs *HTTPServer) SetHelpFlag(c *contextmodel.ReqContext) response.Response
// 403: forbiddenError
// 500: internalServerError
func (hs *HTTPServer) ClearHelpFlags(c *contextmodel.ReqContext) response.Response {
userID, errResponse := getUserID(c)
userID, errResponse := hs.getUserID(c)
if errResponse != nil {
return errResponse
}
@@ -627,9 +628,10 @@ func (hs *HTTPServer) ClearHelpFlags(c *contextmodel.ReqContext) response.Respon
return response.JSON(http.StatusOK, &util.DynMap{"message": "Help flag set", "helpFlags1": flags})
}
func getUserID(c *contextmodel.ReqContext) (int64, *response.NormalResponse) {
func (hs *HTTPServer) getUserID(c *contextmodel.ReqContext) (int64, *response.NormalResponse) {
if !c.SignedInUser.IsIdentityType(claims.TypeUser) {
return 0, response.Error(http.StatusForbidden, "Endpoint only available for users", nil)
hs.log.Debug("Requested endpoint only available to users")
return 0, response.Error(http.StatusNotModified, "Endpoint only available for users", nil)
}
userID, err := c.SignedInUser.GetInternalID()