mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
				
	
	
		
			107 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			107 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
package query
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"strings"
 | 
						|
 | 
						|
	"github.com/grafana/grafana-plugin-sdk-go/backend"
 | 
						|
 | 
						|
	"github.com/grafana/grafana/pkg/components/simplejson"
 | 
						|
	"github.com/grafana/grafana/pkg/services/contexthandler"
 | 
						|
	"github.com/grafana/grafana/pkg/services/datasources"
 | 
						|
)
 | 
						|
 | 
						|
type parsedQuery struct {
 | 
						|
	datasource *datasources.DataSource
 | 
						|
	query      backend.DataQuery
 | 
						|
	rawQuery   *simplejson.Json
 | 
						|
}
 | 
						|
 | 
						|
type parsedRequest struct {
 | 
						|
	hasExpression bool
 | 
						|
	parsedQueries map[string][]parsedQuery
 | 
						|
	dsTypes       map[string]bool
 | 
						|
}
 | 
						|
 | 
						|
func (pr parsedRequest) getFlattenedQueries() []parsedQuery {
 | 
						|
	queries := make([]parsedQuery, 0)
 | 
						|
	for _, pq := range pr.parsedQueries {
 | 
						|
		queries = append(queries, pq...)
 | 
						|
	}
 | 
						|
	return queries
 | 
						|
}
 | 
						|
 | 
						|
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 {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	httpReq := reqCtx.Req
 | 
						|
 | 
						|
	if pr.hasExpression {
 | 
						|
		hasExpr := httpReq.URL.Query().Get("expression")
 | 
						|
		if hasExpr == "" || hasExpr == "true" {
 | 
						|
			return nil
 | 
						|
		}
 | 
						|
		return ErrQueryParamMismatch
 | 
						|
	}
 | 
						|
 | 
						|
	vals := splitHeaders(httpReq.Header.Values(HeaderDatasourceUID))
 | 
						|
	count := len(vals)
 | 
						|
	if count > 0 { // header exists
 | 
						|
		if count != len(pr.parsedQueries) {
 | 
						|
			return ErrQueryParamMismatch
 | 
						|
		}
 | 
						|
		for _, t := range vals {
 | 
						|
			if pr.parsedQueries[t] == nil {
 | 
						|
				return ErrQueryParamMismatch
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	vals = splitHeaders(httpReq.Header.Values(HeaderPluginID))
 | 
						|
	count = len(vals)
 | 
						|
	if count > 0 { // header exists
 | 
						|
		if count != len(pr.dsTypes) {
 | 
						|
			return ErrQueryParamMismatch
 | 
						|
		}
 | 
						|
		for _, t := range vals {
 | 
						|
			if !pr.dsTypes[t] {
 | 
						|
				return ErrQueryParamMismatch
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func splitHeaders(headers []string) []string {
 | 
						|
	out := []string{}
 | 
						|
	for _, v := range headers {
 | 
						|
		if strings.Contains(v, ",") {
 | 
						|
			for _, sub := range strings.Split(v, ",") {
 | 
						|
				out = append(out, strings.TrimSpace(sub))
 | 
						|
			}
 | 
						|
		} else {
 | 
						|
			out = append(out, v)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return out
 | 
						|
}
 |