Public Dashboards: Add audit table (#54508)
This PR adds an audit table for public dashboards allowing a user to view all public dashboards on an instance of grafana. The public dashboards team is working on a proposal for adding RBAC support to the audit table for 9.3 Co-authored-by: juanicabanas <juan.cabanas@grafana.com>
This commit is contained in:
co-authored by
juanicabanas
parent
c7c640d903
commit
cc27214dca
@@ -46,30 +46,129 @@ var userViewer = &user.SignedInUser{UserID: 3, OrgID: 1, OrgRole: org.RoleViewer
|
||||
var userViewerRBAC = &user.SignedInUser{UserID: 4, OrgID: 1, OrgRole: org.RoleViewer, Login: "testViewerUserRBAC", Permissions: map[int64]map[string][]string{1: {dashboards.ActionDashboardsRead: {dashboards.ScopeDashboardsAll}}}}
|
||||
var anonymousUser *user.SignedInUser
|
||||
|
||||
type JsonErrResponse struct {
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
func TestAPIFeatureFlag(t *testing.T) {
|
||||
testCases := []struct {
|
||||
Name string
|
||||
Method string
|
||||
Path string
|
||||
}{
|
||||
{
|
||||
Name: "API: Load Dashboard",
|
||||
Method: http.MethodGet,
|
||||
Path: "/api/public/dashboards/acbc123",
|
||||
},
|
||||
{
|
||||
Name: "API: Query Dashboard",
|
||||
Method: http.MethodGet,
|
||||
Path: "/api/public/dashboards/abc123/panels/2/query",
|
||||
},
|
||||
{
|
||||
Name: "API: List Dashboards",
|
||||
Method: http.MethodGet,
|
||||
Path: "/api/dashboards/public",
|
||||
},
|
||||
{
|
||||
Name: "API: Get Public Dashboard Config",
|
||||
Method: http.MethodPost,
|
||||
Path: "/api/dashboards/uid/abc123/public-config",
|
||||
},
|
||||
{
|
||||
Name: "API: Upate Public Dashboard",
|
||||
Method: http.MethodPost,
|
||||
Path: "/api/dashboards/uid/abc123/public-config",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
t.Run(test.Name, func(t *testing.T) {
|
||||
cfg := setting.NewCfg()
|
||||
cfg.RBACEnabled = false
|
||||
service := publicdashboards.NewFakePublicDashboardService(t)
|
||||
features := featuremgmt.WithFeatures()
|
||||
testServer := setupTestServer(t, cfg, features, service, nil, userAdmin)
|
||||
response := callAPI(testServer, test.Method, test.Path, nil, t)
|
||||
assert.Equal(t, http.StatusNotFound, response.Code)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAPIListPublicDashboard(t *testing.T) {
|
||||
successResp := []PublicDashboardListResponse{
|
||||
{
|
||||
Uid: "1234asdfasdf",
|
||||
AccessToken: "asdfasdf",
|
||||
DashboardUid: "abc1234",
|
||||
IsEnabled: true,
|
||||
},
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
Name string
|
||||
User *user.SignedInUser
|
||||
Response []PublicDashboardListResponse
|
||||
ResponseErr error
|
||||
ExpectedHttpResponse int
|
||||
}{
|
||||
{
|
||||
Name: "Anonymous user cannot list dashboards",
|
||||
User: anonymousUser,
|
||||
Response: successResp,
|
||||
ResponseErr: nil,
|
||||
ExpectedHttpResponse: http.StatusUnauthorized,
|
||||
},
|
||||
{
|
||||
Name: "User viewer can see public dashboards",
|
||||
User: userViewer,
|
||||
Response: successResp,
|
||||
ResponseErr: nil,
|
||||
ExpectedHttpResponse: http.StatusOK,
|
||||
},
|
||||
{
|
||||
Name: "Handles Service error",
|
||||
User: userViewer,
|
||||
Response: nil,
|
||||
ResponseErr: errors.New("error, service broken"),
|
||||
ExpectedHttpResponse: http.StatusInternalServerError,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
t.Run(test.Name, func(t *testing.T) {
|
||||
service := publicdashboards.NewFakePublicDashboardService(t)
|
||||
service.On("ListPublicDashboards", mock.Anything, mock.Anything).
|
||||
Return(test.Response, test.ResponseErr).Maybe()
|
||||
|
||||
cfg := setting.NewCfg()
|
||||
cfg.RBACEnabled = false
|
||||
features := featuremgmt.WithFeatures(featuremgmt.FlagPublicDashboards)
|
||||
testServer := setupTestServer(t, cfg, features, service, nil, test.User)
|
||||
|
||||
response := callAPI(testServer, http.MethodGet, "/api/dashboards/public", nil, t)
|
||||
assert.Equal(t, test.ExpectedHttpResponse, response.Code)
|
||||
|
||||
if test.ExpectedHttpResponse == http.StatusOK {
|
||||
var jsonResp []PublicDashboardListResponse
|
||||
err := json.Unmarshal(response.Body.Bytes(), &jsonResp)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, jsonResp[0].Uid, "1234asdfasdf")
|
||||
}
|
||||
|
||||
if test.ResponseErr != nil {
|
||||
var errResp JsonErrResponse
|
||||
err := json.Unmarshal(response.Body.Bytes(), &errResp)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "error, service broken", errResp.Error)
|
||||
service.AssertNotCalled(t, "ListPublicDashboards")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAPIGetPublicDashboard(t *testing.T) {
|
||||
t.Run("It should 404 if featureflag is not enabled", func(t *testing.T) {
|
||||
cfg := setting.NewCfg()
|
||||
cfg.RBACEnabled = false
|
||||
service := publicdashboards.NewFakePublicDashboardService(t)
|
||||
service.On("GetPublicDashboard", mock.Anything, mock.AnythingOfType("string")).
|
||||
Return(&PublicDashboard{}, &models.Dashboard{}, nil).Maybe()
|
||||
service.On("GetPublicDashboardConfig", mock.Anything, mock.AnythingOfType("int64"), mock.AnythingOfType("string")).
|
||||
Return(&PublicDashboard{}, nil).Maybe()
|
||||
|
||||
testServer := setupTestServer(t, cfg, featuremgmt.WithFeatures(), service, nil, anonymousUser)
|
||||
|
||||
response := callAPI(testServer, http.MethodGet, "/api/public/dashboards", nil, t)
|
||||
assert.Equal(t, http.StatusNotFound, response.Code)
|
||||
|
||||
response = callAPI(testServer, http.MethodGet, "/api/public/dashboards/asdf", nil, t)
|
||||
assert.Equal(t, http.StatusNotFound, response.Code)
|
||||
|
||||
// control set. make sure routes are mounted
|
||||
testServer = setupTestServer(t, cfg, featuremgmt.WithFeatures(featuremgmt.FlagPublicDashboards), service, nil, userAdmin)
|
||||
response = callAPI(testServer, http.MethodGet, "/api/public/dashboards/asdf", nil, t)
|
||||
assert.NotEqual(t, http.StatusNotFound, response.Code)
|
||||
})
|
||||
|
||||
DashboardUid := "dashboard-abcd1234"
|
||||
token, err := uuid.NewRandom()
|
||||
require.NoError(t, err)
|
||||
@@ -138,9 +237,7 @@ func TestAPIGetPublicDashboard(t *testing.T) {
|
||||
assert.Equal(t, false, dashResp.Meta.CanDelete)
|
||||
assert.Equal(t, false, dashResp.Meta.CanSave)
|
||||
} else {
|
||||
var errResp struct {
|
||||
Error string `json:"error"`
|
||||
}
|
||||
var errResp JsonErrResponse
|
||||
err := json.Unmarshal(response.Body.Bytes(), &errResp)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, test.Err.Error(), errResp.Error)
|
||||
@@ -435,12 +532,6 @@ func TestAPIQueryPublicDashboard(t *testing.T) {
|
||||
return testServer, service
|
||||
}
|
||||
|
||||
t.Run("Status code is 404 when feature toggle is disabled", func(t *testing.T) {
|
||||
server, _ := setup(false)
|
||||
resp := callAPI(server, http.MethodPost, "/api/public/dashboards/abc123/panels/2/query", strings.NewReader("{}"), t)
|
||||
require.Equal(t, http.StatusNotFound, resp.Code)
|
||||
})
|
||||
|
||||
t.Run("Status code is 400 when the panel ID is invalid", func(t *testing.T) {
|
||||
server, _ := setup(true)
|
||||
resp := callAPI(server, http.MethodPost, "/api/public/dashboards/abc123/panels/notanumber/query", strings.NewReader("{}"), t)
|
||||
|
||||
Reference in New Issue
Block a user