Chore: Validate batch query refIds (#63018)

This commit is contained in:
Andres Martinez Gotor 2023-02-09 10:11:16 +01:00 committed by GitHub
parent 2a34293689
commit 00b692c0f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 2 deletions

View File

@ -9,4 +9,5 @@ var (
ErrInvalidDatasourceID = errutil.NewBase(errutil.StatusBadRequest, "query.invalidDatasourceId", errutil.WithPublicMessage("Query does not contain a valid data source identifier")).Errorf("invalid data source identifier")
ErrMissingDataSourceInfo = errutil.NewBase(errutil.StatusBadRequest, "query.missingDataSourceInfo").MustTemplate("query missing datasource info: {{ .Public.RefId }}", errutil.WithPublic("Query {{ .Public.RefId }} is missing datasource information"))
ErrQueryParamMismatch = errutil.NewBase(errutil.StatusBadRequest, "query.headerMismatch", errutil.WithPublicMessage("The request headers point to a different plugin than is defined in the request body")).Errorf("plugin header/body mismatch")
ErrDuplicateRefId = errutil.NewBase(errutil.StatusBadRequest, "query.duplicateRefId", errutil.WithPublicMessage("Multiple queries using the same RefId is not allowed ")).Errorf("multiple queries using the same RefId is not allowed")
)

View File

@ -32,6 +32,21 @@ func (pr parsedRequest) getFlattenedQueries() []parsedQuery {
}
func (pr parsedRequest) validateRequest(ctx context.Context) error {
refIds := make(map[string]bool)
for _, pq := range pr.parsedQueries {
for _, q := range pq {
if refIds[q.query.RefID] {
return ErrDuplicateRefId
}
refIds[q.query.RefID] = true
}
}
// Skip header validation. See https://github.com/grafana/grafana/pull/58871
if true {
return nil
}
reqCtx := contexthandler.FromContext(ctx)
if reqCtx == nil || reqCtx.Req == nil {

View File

@ -295,8 +295,7 @@ func (s *Service) parseMetricRequest(ctx context.Context, user *user.SignedInUse
})
}
_ = req.validateRequest(ctx)
return req, nil // TODO req.validateRequest()
return req, req.validateRequest(ctx)
}
func (s *Service) getDataSourceFromQuery(ctx context.Context, user *user.SignedInUser, skipCache bool, query *simplejson.Json, history map[string]*datasources.DataSource) (*datasources.DataSource, error) {

View File

@ -235,6 +235,25 @@ func TestParseMetricRequest(t *testing.T) {
_, err = tc.queryService.parseMetricRequest(httpreq.Context(), tc.signedInUser, true, mr)
require.NoError(t, err)
})
t.Run("Test a duplicated refId", func(t *testing.T) {
tc := setup(t)
mr := metricRequestWithQueries(t, `{
"refId": "A",
"datasource": {
"uid": "gIEkMvIVz",
"type": "postgres"
}
}`, `{
"refId": "A",
"datasource": {
"uid": "gIEkMvIVz",
"type": "postgres"
}
}`)
_, err := tc.queryService.parseMetricRequest(context.Background(), tc.signedInUser, true, mr)
require.Error(t, err)
})
}
func TestQueryDataMultipleSources(t *testing.T) {