mirror of
https://github.com/grafana/grafana.git
synced 2024-11-27 03:11:01 -06:00
c5c34ed95e
* RBAC: Rewrite rbac provisioning api tests
188 lines
5.6 KiB
Go
188 lines
5.6 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"net/http"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
|
"github.com/grafana/grafana/pkg/services/provisioning"
|
|
"github.com/grafana/grafana/pkg/setting"
|
|
"github.com/grafana/grafana/pkg/web/webtest"
|
|
)
|
|
|
|
func TestAPI_AdminProvisioningReload_AccessControl(t *testing.T) {
|
|
type testCase struct {
|
|
desc string
|
|
url string
|
|
expectedBody string
|
|
expectedCode int
|
|
permissions []accesscontrol.Permission
|
|
checkCall func(mock provisioning.ProvisioningServiceMock)
|
|
}
|
|
tests := []testCase{
|
|
{
|
|
desc: "should work for dashboards with specific scope",
|
|
expectedCode: http.StatusOK,
|
|
expectedBody: `{"message":"Dashboards config reloaded"}`,
|
|
permissions: []accesscontrol.Permission{
|
|
{
|
|
Action: ActionProvisioningReload,
|
|
Scope: ScopeProvisionersDashboards,
|
|
},
|
|
},
|
|
url: "/api/admin/provisioning/dashboards/reload",
|
|
checkCall: func(mock provisioning.ProvisioningServiceMock) {
|
|
assert.Len(t, mock.Calls.ProvisionDashboards, 1)
|
|
},
|
|
},
|
|
{
|
|
desc: "should work for dashboards with broader scope",
|
|
expectedCode: http.StatusOK,
|
|
expectedBody: `{"message":"Dashboards config reloaded"}`,
|
|
permissions: []accesscontrol.Permission{
|
|
{
|
|
Action: ActionProvisioningReload,
|
|
Scope: ScopeProvisionersAll,
|
|
},
|
|
},
|
|
url: "/api/admin/provisioning/dashboards/reload",
|
|
checkCall: func(mock provisioning.ProvisioningServiceMock) {
|
|
assert.Len(t, mock.Calls.ProvisionDashboards, 1)
|
|
},
|
|
},
|
|
{
|
|
desc: "should fail for dashboard with wrong scope",
|
|
expectedCode: http.StatusForbidden,
|
|
permissions: []accesscontrol.Permission{
|
|
{
|
|
Action: ActionProvisioningReload,
|
|
Scope: "services:noservice",
|
|
},
|
|
},
|
|
url: "/api/admin/provisioning/dashboards/reload",
|
|
},
|
|
{
|
|
desc: "should fail for dashboard with no permission",
|
|
expectedCode: http.StatusForbidden,
|
|
url: "/api/admin/provisioning/dashboards/reload",
|
|
},
|
|
{
|
|
desc: "should work for notifications with specific scope",
|
|
expectedCode: http.StatusOK,
|
|
expectedBody: `{"message":"Notifications config reloaded"}`,
|
|
permissions: []accesscontrol.Permission{
|
|
{
|
|
Action: ActionProvisioningReload,
|
|
Scope: ScopeProvisionersNotifications,
|
|
},
|
|
},
|
|
url: "/api/admin/provisioning/notifications/reload",
|
|
checkCall: func(mock provisioning.ProvisioningServiceMock) {
|
|
assert.Len(t, mock.Calls.ProvisionNotifications, 1)
|
|
},
|
|
},
|
|
{
|
|
desc: "should fail for notifications with no permission",
|
|
expectedCode: http.StatusForbidden,
|
|
url: "/api/admin/provisioning/notifications/reload",
|
|
},
|
|
{
|
|
desc: "should work for datasources with specific scope",
|
|
expectedCode: http.StatusOK,
|
|
expectedBody: `{"message":"Datasources config reloaded"}`,
|
|
permissions: []accesscontrol.Permission{
|
|
{
|
|
Action: ActionProvisioningReload,
|
|
Scope: ScopeProvisionersDatasources,
|
|
},
|
|
},
|
|
url: "/api/admin/provisioning/datasources/reload",
|
|
checkCall: func(mock provisioning.ProvisioningServiceMock) {
|
|
assert.Len(t, mock.Calls.ProvisionDatasources, 1)
|
|
},
|
|
},
|
|
{
|
|
desc: "should fail for datasources with no permission",
|
|
expectedCode: http.StatusForbidden,
|
|
url: "/api/admin/provisioning/datasources/reload",
|
|
},
|
|
{
|
|
desc: "should work for plugins with specific scope",
|
|
expectedCode: http.StatusOK,
|
|
expectedBody: `{"message":"Plugins config reloaded"}`,
|
|
permissions: []accesscontrol.Permission{
|
|
{
|
|
Action: ActionProvisioningReload,
|
|
Scope: ScopeProvisionersPlugins,
|
|
},
|
|
},
|
|
url: "/api/admin/provisioning/plugins/reload",
|
|
checkCall: func(mock provisioning.ProvisioningServiceMock) {
|
|
assert.Len(t, mock.Calls.ProvisionPlugins, 1)
|
|
},
|
|
},
|
|
{
|
|
desc: "should fail for plugins with no permission",
|
|
expectedCode: http.StatusForbidden,
|
|
url: "/api/admin/provisioning/plugins/reload",
|
|
},
|
|
{
|
|
desc: "should fail for alerting with no permission",
|
|
expectedCode: http.StatusForbidden,
|
|
url: "/api/admin/provisioning/alerting/reload",
|
|
},
|
|
{
|
|
desc: "should work for alert rules with specific scope",
|
|
expectedCode: http.StatusOK,
|
|
expectedBody: `{"message":"Alerting config reloaded"}`,
|
|
permissions: []accesscontrol.Permission{
|
|
{
|
|
Action: ActionProvisioningReload,
|
|
Scope: ScopeProvisionersAlertRules,
|
|
},
|
|
},
|
|
url: "/api/admin/provisioning/alerting/reload",
|
|
checkCall: func(mock provisioning.ProvisioningServiceMock) {
|
|
assert.Len(t, mock.Calls.ProvisionAlerting, 1)
|
|
},
|
|
},
|
|
{
|
|
desc: "should fail for alerting with no permission",
|
|
expectedCode: http.StatusForbidden,
|
|
url: "/api/admin/provisioning/alerting/reload",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.desc, func(t *testing.T) {
|
|
pService := provisioning.NewProvisioningServiceMock(context.Background())
|
|
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
|
hs.Cfg = setting.NewCfg()
|
|
hs.ProvisioningService = pService
|
|
})
|
|
|
|
res, err := server.Send(webtest.RequestWithSignedInUser(server.NewPostRequest(tt.url, nil), userWithPermissions(1, tt.permissions)))
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.expectedCode, res.StatusCode)
|
|
|
|
if tt.expectedCode == http.StatusOK {
|
|
body, err := io.ReadAll(res.Body)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.expectedBody, string(body))
|
|
}
|
|
|
|
require.NoError(t, res.Body.Close())
|
|
|
|
if tt.checkCall != nil {
|
|
// Check we actually called the provisioning service
|
|
tt.checkCall(*pService)
|
|
}
|
|
})
|
|
}
|
|
}
|