/
settings.go
255 lines (239 loc) · 8.56 KB
/
settings.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
package models
import (
"encoding/json"
"errors"
"fmt"
"net/textproto"
"strings"
"github.com/grafana/grafana-plugin-sdk-go/backend"
)
const (
AuthenticationMethodNone = "none"
AuthenticationMethodBasic = "basicAuth"
AuthenticationMethodApiKey = "apiKey"
AuthenticationMethodBearerToken = "bearerToken"
AuthenticationMethodForwardOauth = "oauthPassThru"
AuthenticationMethodDigestAuth = "digestAuth"
AuthenticationMethodOAuth = "oauth2"
AuthenticationMethodAWS = "aws"
)
const (
AuthOAuthTypeClientCredentials = "client_credentials"
AuthOAuthJWT = "jwt"
AuthOAuthOthers = "others"
)
const (
ApiKeyTypeHeader = "header"
ApiKeyTypeQuery = "query"
)
type OAuth2Settings struct {
OAuth2Type string `json:"oauth2_type,omitempty"`
ClientID string `json:"client_id,omitempty"`
TokenURL string `json:"token_url,omitempty"`
Email string `json:"email,omitempty"`
PrivateKeyID string `json:"private_key_id,omitempty"`
Subject string `json:"subject,omitempty"`
Scopes []string `json:"scopes,omitempty"`
ClientSecret string
PrivateKey string
EndpointParams map[string]string
}
type AWSAuthType string
const (
AWSAuthTypeKeys AWSAuthType = "keys"
)
type AWSSettings struct {
AuthType AWSAuthType `json:"authType"`
Region string `json:"region"`
Service string `json:"service"`
}
type InfinitySettings struct {
AuthenticationMethod string
OAuth2Settings OAuth2Settings
BearerToken string
ApiKeyKey string
ApiKeyType string
ApiKeyValue string
AWSSettings AWSSettings
AWSAccessKey string
AWSSecretKey string
URL string
BasicAuthEnabled bool
UserName string
Password string
ForwardOauthIdentity bool
CustomHeaders map[string]string
SecureQueryFields map[string]string
InsecureSkipVerify bool
ServerName string
TimeoutInSeconds int64
TLSClientAuth bool
TLSAuthWithCACert bool
TLSCACert string
TLSClientCert string
TLSClientKey string
AllowedHosts []string
EnableOpenAPI bool
OpenAPIVersion string
OpenAPIUrl string
OpenAPIBaseUrl string
ReferenceData []RefData
}
func (s *InfinitySettings) Validate() error {
if (s.BasicAuthEnabled || s.AuthenticationMethod == AuthenticationMethodBasic || s.AuthenticationMethod == AuthenticationMethodDigestAuth) && s.Password == "" {
return errors.New("invalid or empty password detected")
}
if s.AuthenticationMethod == AuthenticationMethodApiKey && (s.ApiKeyValue == "" || s.ApiKeyKey == "") {
return errors.New("invalid API key specified")
}
if s.AuthenticationMethod == AuthenticationMethodBearerToken && s.BearerToken == "" {
return errors.New("invalid or empty bearer token detected")
}
if s.AuthenticationMethod != AuthenticationMethodNone && len(s.AllowedHosts) < 1 {
return errors.New("configure allowed hosts in the authentication section")
}
if s.HaveSecureHeaders() && len(s.AllowedHosts) < 1 {
return errors.New("configure allowed hosts in the authentication section")
}
return nil
}
func (s *InfinitySettings) HaveSecureHeaders() bool {
if len(s.CustomHeaders) > 0 {
for k := range s.CustomHeaders {
if textproto.CanonicalMIMEHeaderKey(k) == "Accept" {
continue
}
if textproto.CanonicalMIMEHeaderKey(k) == "Content-Type" {
continue
}
return true
}
return false
}
return false
}
type RefData struct {
Name string `json:"name,omitempty"`
Data string `json:"data,omitempty"`
}
type InfinitySettingsJson struct {
AuthenticationMethod string `json:"auth_method,omitempty"`
APIKeyKey string `json:"apiKeyKey,omitempty"`
APIKeyType string `json:"apiKeyType,omitempty"`
OAuth2Settings OAuth2Settings `json:"oauth2,omitempty"`
AWSSettings AWSSettings `json:"aws,omitempty"`
ForwardOauthIdentity bool `json:"oauthPassThru,omitempty"`
InsecureSkipVerify bool `json:"tlsSkipVerify,omitempty"`
ServerName string `json:"serverName,omitempty"`
TLSClientAuth bool `json:"tlsAuth,omitempty"`
TLSAuthWithCACert bool `json:"tlsAuthWithCACert,omitempty"`
TimeoutInSeconds int64 `json:"timeoutInSeconds,omitempty"`
AllowedHosts []string `json:"allowedHosts,omitempty"`
EnableOpenAPI bool `json:"enableOpenApi,omitempty"`
OpenAPIVersion string `json:"openApiVersion,omitempty"`
OpenAPIUrl string `json:"openApiUrl,omitempty"`
OpenAPIBaseUrl string `json:"openAPIBaseURL,omitempty"`
ReferenceData []RefData `json:"refData,omitempty"`
}
func LoadSettings(config backend.DataSourceInstanceSettings) (settings InfinitySettings, err error) {
settings.URL = config.URL
if config.URL == "__IGNORE_URL__" {
settings.URL = ""
}
settings.BasicAuthEnabled = config.BasicAuthEnabled
settings.UserName = config.BasicAuthUser
infJson := InfinitySettingsJson{}
if config.JSONData != nil {
if err := json.Unmarshal(config.JSONData, &infJson); err != nil {
return settings, err
}
settings.AuthenticationMethod = infJson.AuthenticationMethod
settings.OAuth2Settings = infJson.OAuth2Settings
if settings.AuthenticationMethod == "oauth2" && settings.OAuth2Settings.OAuth2Type == "" {
settings.OAuth2Settings.OAuth2Type = "client_credentials"
}
settings.ApiKeyKey = infJson.APIKeyKey
settings.ApiKeyType = infJson.APIKeyType
settings.AWSSettings = infJson.AWSSettings
if settings.ApiKeyType == "" {
settings.ApiKeyType = "header"
}
if val, ok := config.DecryptedSecureJSONData["apiKeyValue"]; ok {
settings.ApiKeyValue = val
}
settings.ForwardOauthIdentity = infJson.ForwardOauthIdentity
settings.InsecureSkipVerify = infJson.InsecureSkipVerify
settings.ServerName = infJson.ServerName
settings.TLSClientAuth = infJson.TLSClientAuth
settings.TLSAuthWithCACert = infJson.TLSAuthWithCACert
settings.TimeoutInSeconds = 60
if infJson.TimeoutInSeconds > 0 {
settings.TimeoutInSeconds = infJson.TimeoutInSeconds
}
if len(infJson.AllowedHosts) > 0 {
settings.AllowedHosts = infJson.AllowedHosts
}
}
settings.EnableOpenAPI = infJson.EnableOpenAPI
settings.OpenAPIVersion = infJson.OpenAPIVersion
settings.OpenAPIUrl = infJson.OpenAPIUrl
settings.OpenAPIBaseUrl = infJson.OpenAPIBaseUrl
settings.ReferenceData = infJson.ReferenceData
if val, ok := config.DecryptedSecureJSONData["basicAuthPassword"]; ok {
settings.Password = val
}
if val, ok := config.DecryptedSecureJSONData["oauth2ClientSecret"]; ok {
settings.OAuth2Settings.ClientSecret = val
}
if val, ok := config.DecryptedSecureJSONData["oauth2JWTPrivateKey"]; ok {
settings.OAuth2Settings.PrivateKey = val
}
if val, ok := config.DecryptedSecureJSONData["tlsCACert"]; ok {
settings.TLSCACert = val
}
if val, ok := config.DecryptedSecureJSONData["tlsClientCert"]; ok {
settings.TLSClientCert = val
}
if val, ok := config.DecryptedSecureJSONData["tlsClientKey"]; ok {
settings.TLSClientKey = val
}
if val, ok := config.DecryptedSecureJSONData["bearerToken"]; ok {
settings.BearerToken = val
}
if val, ok := config.DecryptedSecureJSONData["awsAccessKey"]; ok {
settings.AWSAccessKey = val
}
if val, ok := config.DecryptedSecureJSONData["awsSecretKey"]; ok {
settings.AWSSecretKey = val
}
settings.CustomHeaders = GetSecrets(config, "httpHeaderName", "httpHeaderValue")
settings.SecureQueryFields = GetSecrets(config, "secureQueryName", "secureQueryValue")
settings.OAuth2Settings.EndpointParams = GetSecrets(config, "oauth2EndPointParamsName", "oauth2EndPointParamsValue")
if settings.AuthenticationMethod == "" {
settings.AuthenticationMethod = AuthenticationMethodNone
if settings.BasicAuthEnabled {
settings.AuthenticationMethod = AuthenticationMethodBasic
}
if settings.ForwardOauthIdentity {
settings.AuthenticationMethod = AuthenticationMethodForwardOauth
}
}
return
}
func GetSecrets(config backend.DataSourceInstanceSettings, secretType string, secretValue string) map[string]string {
headers := make(map[string]string)
JsonData := make(map[string]any)
if err := json.Unmarshal(config.JSONData, &JsonData); err != nil {
return headers
}
if JsonData == nil {
return headers
}
for key, value := range JsonData {
if strings.HasPrefix(key, secretType) {
header_key := fmt.Sprintf("%v", value)
headers[header_key] = config.DecryptedSecureJSONData[strings.Replace(key, secretType, secretValue, 1)]
}
}
return headers
}