mirror of
https://github.com/grafana/grafana.git
synced 2025-09-24 08:14:00 +08:00
87 lines
2.6 KiB
Go
87 lines
2.6 KiB
Go
package httpclientprovider
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"path"
|
|
|
|
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
|
|
"github.com/grafana/grafana/pkg/setting"
|
|
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/azcredentials"
|
|
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/aztokenprovider"
|
|
)
|
|
|
|
const azureMiddlewareName = "AzureAuthentication.Provider"
|
|
|
|
func AzureMiddleware(cfg *setting.Cfg) httpclient.Middleware {
|
|
return httpclient.NamedMiddlewareFunc(azureMiddlewareName, func(opts httpclient.Options, next http.RoundTripper) http.RoundTripper {
|
|
credentials, err := getAzureCredentials(opts.CustomOptions)
|
|
if err != nil {
|
|
return errorResponse(err)
|
|
} else if credentials == nil {
|
|
return next
|
|
}
|
|
|
|
tokenProvider, err := aztokenprovider.NewAzureAccessTokenProvider(cfg, credentials)
|
|
if err != nil {
|
|
return errorResponse(err)
|
|
}
|
|
|
|
scopes, err := getAzureEndpointScopes(opts.CustomOptions)
|
|
if err != nil {
|
|
return errorResponse(err)
|
|
}
|
|
|
|
return aztokenprovider.ApplyAuth(tokenProvider, scopes, next)
|
|
})
|
|
}
|
|
|
|
func errorResponse(err error) http.RoundTripper {
|
|
return httpclient.RoundTripperFunc(func(req *http.Request) (*http.Response, error) {
|
|
return nil, fmt.Errorf("invalid Azure configuration: %s", err)
|
|
})
|
|
}
|
|
|
|
func getAzureCredentials(customOptions map[string]interface{}) (azcredentials.AzureCredentials, error) {
|
|
if untypedValue, ok := customOptions["_azureCredentials"]; !ok {
|
|
return nil, nil
|
|
} else if value, ok := untypedValue.(azcredentials.AzureCredentials); !ok {
|
|
err := fmt.Errorf("the field 'azureCredentials' should be a valid credentials object")
|
|
return nil, err
|
|
} else {
|
|
return value, nil
|
|
}
|
|
}
|
|
|
|
func getAzureEndpointResourceId(customOptions map[string]interface{}) (*url.URL, error) {
|
|
var value string
|
|
if untypedValue, ok := customOptions["azureEndpointResourceId"]; !ok {
|
|
err := fmt.Errorf("the field 'azureEndpointResourceId' should be set")
|
|
return nil, err
|
|
} else if value, ok = untypedValue.(string); !ok {
|
|
err := fmt.Errorf("the field 'azureEndpointResourceId' should be a string")
|
|
return nil, err
|
|
}
|
|
|
|
resourceId, err := url.Parse(value)
|
|
if err != nil || resourceId.Scheme == "" || resourceId.Host == "" {
|
|
err := fmt.Errorf("invalid endpoint Resource ID URL '%s'", value)
|
|
return nil, err
|
|
}
|
|
|
|
return resourceId, nil
|
|
}
|
|
|
|
func getAzureEndpointScopes(customOptions map[string]interface{}) ([]string, error) {
|
|
resourceId, err := getAzureEndpointResourceId(customOptions)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
resourceId.Path = path.Join(resourceId.Path, ".default")
|
|
scopes := []string{resourceId.String()}
|
|
|
|
return scopes, nil
|
|
}
|