mirror of
https://github.com/grafana/grafana.git
synced 2025-02-11 08:05:43 -06:00
* use 403 for authorization error * update silences API * add ForbiddenError to rule API responses
131 lines
4.3 KiB
Go
131 lines
4.3 KiB
Go
package alerting
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/grafana/grafana-plugin-sdk-go/data"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
|
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions"
|
|
"github.com/grafana/grafana/pkg/services/datasources"
|
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
|
"github.com/grafana/grafana/pkg/services/org"
|
|
"github.com/grafana/grafana/pkg/services/user"
|
|
"github.com/grafana/grafana/pkg/tests/testinfra"
|
|
)
|
|
|
|
func TestBacktesting(t *testing.T) {
|
|
dir, path := testinfra.CreateGrafDir(t, testinfra.GrafanaOpts{
|
|
DisableLegacyAlerting: true,
|
|
EnableUnifiedAlerting: true,
|
|
DisableAnonymous: true,
|
|
AppModeProduction: true,
|
|
EnableFeatureToggles: []string{
|
|
featuremgmt.FlagAlertingBacktesting,
|
|
},
|
|
EnableLog: false,
|
|
})
|
|
|
|
grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, path)
|
|
|
|
userId := createUser(t, env.SQLStore, user.CreateUserCommand{
|
|
DefaultOrgRole: string(org.RoleAdmin),
|
|
Password: "admin",
|
|
Login: "admin",
|
|
})
|
|
|
|
apiCli := newAlertingApiClient(grafanaListedAddr, "admin", "admin")
|
|
|
|
input, err := os.ReadFile(filepath.Join("api_backtesting_data.json"))
|
|
require.NoError(t, err)
|
|
var testData map[string]apimodels.BacktestConfig
|
|
require.NoError(t, json.Unmarshal(input, &testData))
|
|
|
|
queryRequest, ok := testData["query"]
|
|
require.Truef(t, ok, "The data file does not contain a field `query`")
|
|
|
|
for _, query := range queryRequest.Data {
|
|
if query.DatasourceUID == "__expr__" {
|
|
continue
|
|
}
|
|
t.Logf("Creating a new test data source with UID %s", query.DatasourceUID)
|
|
dsCmd := &datasources.AddDataSourceCommand{
|
|
Name: "Backtesting-TestDatasource",
|
|
Type: "testdata",
|
|
Access: datasources.DS_ACCESS_PROXY,
|
|
UID: query.DatasourceUID,
|
|
UserID: userId,
|
|
OrgID: 1,
|
|
}
|
|
_, err := env.Server.HTTPServer.DataSourcesService.AddDataSource(context.Background(), dsCmd)
|
|
require.NoError(t, err)
|
|
break
|
|
}
|
|
|
|
t.Run("and request contains data", func(t *testing.T) {
|
|
t.Run("should accept request", func(t *testing.T) {
|
|
request, ok := testData["data"]
|
|
require.Truef(t, ok, "The data file does not contain a field `data`")
|
|
|
|
status, body := apiCli.SubmitRuleForBacktesting(t, request)
|
|
require.Equal(t, http.StatusOK, status)
|
|
var result data.Frame
|
|
require.NoErrorf(t, json.Unmarshal([]byte(body), &result), "cannot parse response to data frame")
|
|
})
|
|
})
|
|
|
|
t.Run("and request contains query", func(t *testing.T) {
|
|
t.Run("should accept request with query", func(t *testing.T) {
|
|
status, body := apiCli.SubmitRuleForBacktesting(t, queryRequest)
|
|
require.Equalf(t, http.StatusOK, status, "Response: %s", body)
|
|
var result data.Frame
|
|
require.NoErrorf(t, json.Unmarshal([]byte(body), &result), "cannot parse response to data frame")
|
|
})
|
|
})
|
|
|
|
t.Run("if user does not have permissions", func(t *testing.T) {
|
|
testUserId := createUser(t, env.SQLStore, user.CreateUserCommand{
|
|
DefaultOrgRole: "",
|
|
Password: "test",
|
|
Login: "test",
|
|
})
|
|
|
|
testUserApiCli := newAlertingApiClient(grafanaListedAddr, "test", "test")
|
|
|
|
t.Run("fail if can't read rules", func(t *testing.T) {
|
|
status, body := testUserApiCli.SubmitRuleForBacktesting(t, queryRequest)
|
|
require.Contains(t, body, accesscontrol.ActionAlertingRuleRead)
|
|
require.Equalf(t, http.StatusForbidden, status, "Response: %s", body)
|
|
})
|
|
|
|
// access control permissions store
|
|
permissionsStore := resourcepermissions.NewStore(env.SQLStore, featuremgmt.WithFeatures())
|
|
_, err := permissionsStore.SetUserResourcePermission(context.Background(),
|
|
accesscontrol.GlobalOrgID,
|
|
accesscontrol.User{ID: testUserId},
|
|
resourcepermissions.SetResourcePermissionCommand{
|
|
Actions: []string{
|
|
accesscontrol.ActionAlertingRuleRead,
|
|
},
|
|
Resource: "folders",
|
|
ResourceID: "*",
|
|
ResourceAttribute: "uid",
|
|
}, nil)
|
|
require.NoError(t, err)
|
|
testUserApiCli.ReloadCachedPermissions(t)
|
|
|
|
t.Run("fail if can't query data sources", func(t *testing.T) {
|
|
status, body := testUserApiCli.SubmitRuleForBacktesting(t, queryRequest)
|
|
require.Contains(t, body, "user is not authorized to access rule group")
|
|
require.Equalf(t, http.StatusForbidden, status, "Response: %s", body)
|
|
})
|
|
})
|
|
}
|