mirror of
https://github.com/grafana/grafana.git
synced 2025-08-02 16:32:28 +08:00
Fix panic when using complex dynamic URLs in app plugin routes (#27977)
* remove unused function to interpolate URLs * share function to add headers between ds/plugin proxies * stop performing unnecessary plugin setting lookup * fix bug causing runtime errors when using complex templated URLs * lower case util functions not used outside of pluginproxy package * change test URL to a (valid) dummy URL to make intent clearer Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com>
This commit is contained in:
@ -4,15 +4,14 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"text/template"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
)
|
||||
|
||||
// InterpolateString accepts template data and return a string with substitutions
|
||||
func InterpolateString(text string, data templateData) (string, error) {
|
||||
// interpolateString accepts template data and return a string with substitutions
|
||||
func interpolateString(text string, data templateData) (string, error) {
|
||||
t, err := template.New("content").Parse(text)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("could not parse template %s", text)
|
||||
@ -27,26 +26,38 @@ func InterpolateString(text string, data templateData) (string, error) {
|
||||
return contentBuf.String(), nil
|
||||
}
|
||||
|
||||
// InterpolateURL accepts template data and return a string with substitutions
|
||||
func InterpolateURL(anURL *url.URL, route *plugins.AppPluginRoute, orgID int64, appID string) (*url.URL, error) {
|
||||
query := models.GetPluginSettingByIdQuery{OrgId: orgID, PluginId: appID}
|
||||
result, err := url.Parse(anURL.String())
|
||||
if query.Result != nil {
|
||||
if len(query.Result.JsonData) > 0 {
|
||||
data := templateData{
|
||||
JsonData: query.Result.JsonData,
|
||||
}
|
||||
interpolatedResult, err := InterpolateString(anURL.String(), data)
|
||||
if err == nil {
|
||||
result, err = url.Parse(interpolatedResult)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing plugin route URL: %w", err)
|
||||
}
|
||||
}
|
||||
// addHeaders interpolates route headers and injects them into the request headers
|
||||
func addHeaders(reqHeaders *http.Header, route *plugins.AppPluginRoute, data templateData) error {
|
||||
for _, header := range route.Headers {
|
||||
interpolated, err := interpolateString(header.Content, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
reqHeaders.Set(header.Name, interpolated)
|
||||
}
|
||||
|
||||
return result, err
|
||||
return nil
|
||||
}
|
||||
|
||||
// addQueryString interpolates route params and injects them into the request object
|
||||
func addQueryString(req *http.Request, route *plugins.AppPluginRoute, data templateData) error {
|
||||
q := req.URL.Query()
|
||||
for _, param := range route.URLParams {
|
||||
interpolatedName, err := interpolateString(param.Name, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
interpolatedContent, err := interpolateString(param.Content, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
q.Add(interpolatedName, interpolatedContent)
|
||||
}
|
||||
req.URL.RawQuery = q.Encode()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Set the X-Grafana-User header if needed (and remove if not)
|
||||
|
Reference in New Issue
Block a user