mirror of https://github.com/grafana/grafana.git
				
				
				
			Merge branch 'master' into mtanda-prometheus_table
This commit is contained in:
		
						commit
						8c448d95a1
					
				|  | @ -23,9 +23,14 @@ func TestPluginProxy(t *testing.T) { | |||
| 		setting.SecretKey = "password" | ||||
| 
 | ||||
| 		bus.AddHandler("test", func(query *m.GetPluginSettingByIdQuery) error { | ||||
| 			key, err := util.Encrypt([]byte("123"), "password") | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 
 | ||||
| 			query.Result = &m.PluginSetting{ | ||||
| 				SecureJsonData: map[string][]byte{ | ||||
| 					"key": util.Encrypt([]byte("123"), "password"), | ||||
| 					"key": key, | ||||
| 				}, | ||||
| 			} | ||||
| 			return nil | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| package securejsondata | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/grafana/grafana/pkg/log" | ||||
| 	"github.com/grafana/grafana/pkg/setting" | ||||
| 	"github.com/grafana/grafana/pkg/util" | ||||
| ) | ||||
|  | @ -10,7 +11,12 @@ type SecureJsonData map[string][]byte | |||
| func (s SecureJsonData) Decrypt() map[string]string { | ||||
| 	decrypted := make(map[string]string) | ||||
| 	for key, data := range s { | ||||
| 		decrypted[key] = string(util.Decrypt(data, setting.SecretKey)) | ||||
| 		decryptedData, err := util.Decrypt(data, setting.SecretKey) | ||||
| 		if err != nil { | ||||
| 			log.Fatal(4, err.Error()) | ||||
| 		} | ||||
| 
 | ||||
| 		decrypted[key] = string(decryptedData) | ||||
| 	} | ||||
| 	return decrypted | ||||
| } | ||||
|  | @ -18,7 +24,12 @@ func (s SecureJsonData) Decrypt() map[string]string { | |||
| func GetEncryptedJsonData(sjd map[string]string) SecureJsonData { | ||||
| 	encrypted := make(SecureJsonData) | ||||
| 	for key, data := range sjd { | ||||
| 		encrypted[key] = util.Encrypt([]byte(data), setting.SecretKey) | ||||
| 		encryptedData, err := util.Encrypt([]byte(data), setting.SecretKey) | ||||
| 		if err != nil { | ||||
| 			log.Fatal(4, err.Error()) | ||||
| 		} | ||||
| 
 | ||||
| 		encrypted[key] = encryptedData | ||||
| 	} | ||||
| 	return encrypted | ||||
| } | ||||
|  |  | |||
|  | @ -15,6 +15,8 @@ import ( | |||
| 	"github.com/go-stack/stack" | ||||
| 	"github.com/inconshreveable/log15" | ||||
| 	"github.com/inconshreveable/log15/term" | ||||
| 
 | ||||
| 	"github.com/grafana/grafana/pkg/util" | ||||
| ) | ||||
| 
 | ||||
| var Root log15.Logger | ||||
|  | @ -172,7 +174,7 @@ func ReadLoggingConfig(modes []string, logsPath string, cfg *ini.File) { | |||
| 	Close() | ||||
| 
 | ||||
| 	defaultLevelName, _ := getLogLevelFromConfig("log", "info", cfg) | ||||
| 	defaultFilters := getFilters(cfg.Section("log").Key("filters").Strings(" ")) | ||||
| 	defaultFilters := getFilters(util.SplitString(cfg.Section("log").Key("filters").String())) | ||||
| 
 | ||||
| 	handlers := make([]log15.Handler, 0) | ||||
| 
 | ||||
|  | @ -185,7 +187,7 @@ func ReadLoggingConfig(modes []string, logsPath string, cfg *ini.File) { | |||
| 
 | ||||
| 		// Log level.
 | ||||
| 		_, level := getLogLevelFromConfig("log."+mode, defaultLevelName, cfg) | ||||
| 		modeFilters := getFilters(sec.Key("filters").Strings(" ")) | ||||
| 		modeFilters := getFilters(util.SplitString(sec.Key("filters").String())) | ||||
| 		format := getLogFormat(sec.Key("format").MustString("")) | ||||
| 
 | ||||
| 		var handler log15.Handler | ||||
|  |  | |||
|  | @ -54,10 +54,15 @@ func TestDataSourceCache(t *testing.T) { | |||
| 		}) | ||||
| 
 | ||||
| 		ds.JsonData = json | ||||
| 
 | ||||
| 		tlsCaCert, _ := util.Encrypt([]byte(caCert), "password") | ||||
| 		tlsClientCert, _ := util.Encrypt([]byte(clientCert), "password") | ||||
| 		tlsClientKey, _ := util.Encrypt([]byte(clientKey), "password") | ||||
| 
 | ||||
| 		ds.SecureJsonData = map[string][]byte{ | ||||
| 			"tlsCACert":     util.Encrypt([]byte(caCert), "password"), | ||||
| 			"tlsClientCert": util.Encrypt([]byte(clientCert), "password"), | ||||
| 			"tlsClientKey":  util.Encrypt([]byte(clientKey), "password"), | ||||
| 			"tlsCACert":     tlsCaCert, | ||||
| 			"tlsClientCert": tlsClientCert, | ||||
| 			"tlsClientKey":  tlsClientKey, | ||||
| 		} | ||||
| 		ds.Updated = t.Add(-1 * time.Minute) | ||||
| 
 | ||||
|  |  | |||
|  | @ -74,7 +74,12 @@ func UpdatePluginSetting(cmd *m.UpdatePluginSettingCmd) error { | |||
| 			return err | ||||
| 		} else { | ||||
| 			for key, data := range cmd.SecureJsonData { | ||||
| 				pluginSetting.SecureJsonData[key] = util.Encrypt([]byte(data), setting.SecretKey) | ||||
| 				encryptedData, err := util.Encrypt([]byte(data), setting.SecretKey) | ||||
| 				if err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 
 | ||||
| 				pluginSetting.SecureJsonData[key] = encryptedData | ||||
| 			} | ||||
| 
 | ||||
| 			// add state change event on commit success
 | ||||
|  |  | |||
|  | @ -509,7 +509,7 @@ func NewConfigContext(args *CommandLineArgs) error { | |||
| 
 | ||||
| 	//  read data source proxy white list
 | ||||
| 	DataProxyWhiteList = make(map[string]bool) | ||||
| 	for _, hostAndIp := range security.Key("data_source_proxy_whitelist").Strings(" ") { | ||||
| 	for _, hostAndIp := range util.SplitString(security.Key("data_source_proxy_whitelist").String()) { | ||||
| 		DataProxyWhiteList[hostAndIp] = true | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -8,6 +8,7 @@ import ( | |||
| 	"golang.org/x/oauth2" | ||||
| 
 | ||||
| 	"github.com/grafana/grafana/pkg/setting" | ||||
| 	"github.com/grafana/grafana/pkg/util" | ||||
| ) | ||||
| 
 | ||||
| type BasicUserInfo struct { | ||||
|  | @ -53,12 +54,12 @@ func NewOAuthService() { | |||
| 		info := &setting.OAuthInfo{ | ||||
| 			ClientId:       sec.Key("client_id").String(), | ||||
| 			ClientSecret:   sec.Key("client_secret").String(), | ||||
| 			Scopes:         sec.Key("scopes").Strings(" "), | ||||
| 			Scopes:         util.SplitString(sec.Key("scopes").String()), | ||||
| 			AuthUrl:        sec.Key("auth_url").String(), | ||||
| 			TokenUrl:       sec.Key("token_url").String(), | ||||
| 			ApiUrl:         sec.Key("api_url").String(), | ||||
| 			Enabled:        sec.Key("enabled").MustBool(), | ||||
| 			AllowedDomains: sec.Key("allowed_domains").Strings(" "), | ||||
| 			AllowedDomains: util.SplitString(sec.Key("allowed_domains").String()), | ||||
| 			HostedDomain:   sec.Key("hosted_domain").String(), | ||||
| 			AllowSignup:    sec.Key("allow_sign_up").MustBool(), | ||||
| 			Name:           sec.Key("name").MustString(name), | ||||
|  | @ -92,7 +93,7 @@ func NewOAuthService() { | |||
| 				apiUrl:               info.ApiUrl, | ||||
| 				allowSignup:          info.AllowSignup, | ||||
| 				teamIds:              sec.Key("team_ids").Ints(","), | ||||
| 				allowedOrganizations: sec.Key("allowed_organizations").Strings(" "), | ||||
| 				allowedOrganizations: util.SplitString(sec.Key("allowed_organizations").String()), | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
|  | @ -115,7 +116,7 @@ func NewOAuthService() { | |||
| 				apiUrl:               info.ApiUrl, | ||||
| 				allowSignup:          info.AllowSignup, | ||||
| 				teamIds:              sec.Key("team_ids").Ints(","), | ||||
| 				allowedOrganizations: sec.Key("allowed_organizations").Strings(" "), | ||||
| 				allowedOrganizations: util.SplitString(sec.Key("allowed_organizations").String()), | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
|  | @ -135,7 +136,7 @@ func NewOAuthService() { | |||
| 				Config:               &config, | ||||
| 				url:                  setting.GrafanaNetUrl, | ||||
| 				allowSignup:          info.AllowSignup, | ||||
| 				allowedOrganizations: sec.Key("allowed_organizations").Strings(" "), | ||||
| 				allowedOrganizations: util.SplitString(sec.Key("allowed_organizations").String()), | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
|  | @ -5,26 +5,25 @@ import ( | |||
| 	"crypto/cipher" | ||||
| 	"crypto/rand" | ||||
| 	"crypto/sha256" | ||||
| 	"errors" | ||||
| 	"io" | ||||
| 
 | ||||
| 	"github.com/grafana/grafana/pkg/log" | ||||
| ) | ||||
| 
 | ||||
| const saltLength = 8 | ||||
| 
 | ||||
| func Decrypt(payload []byte, secret string) []byte { | ||||
| func Decrypt(payload []byte, secret string) ([]byte, error) { | ||||
| 	salt := payload[:saltLength] | ||||
| 	key := encryptionKeyToBytes(secret, string(salt)) | ||||
| 
 | ||||
| 	block, err := aes.NewCipher(key) | ||||
| 	if err != nil { | ||||
| 		log.Fatal(4, err.Error()) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	// The IV needs to be unique, but not secure. Therefore it's common to
 | ||||
| 	// include it at the beginning of the ciphertext.
 | ||||
| 	if len(payload) < aes.BlockSize { | ||||
| 		log.Fatal(4, "payload too short") | ||||
| 		return nil, errors.New("payload too short") | ||||
| 	} | ||||
| 	iv := payload[saltLength : saltLength+aes.BlockSize] | ||||
| 	payload = payload[saltLength+aes.BlockSize:] | ||||
|  | @ -33,16 +32,16 @@ func Decrypt(payload []byte, secret string) []byte { | |||
| 
 | ||||
| 	// XORKeyStream can work in-place if the two arguments are the same.
 | ||||
| 	stream.XORKeyStream(payload, payload) | ||||
| 	return payload | ||||
| 	return payload, nil | ||||
| } | ||||
| 
 | ||||
| func Encrypt(payload []byte, secret string) []byte { | ||||
| func Encrypt(payload []byte, secret string) ([]byte, error) { | ||||
| 	salt := GetRandomString(saltLength) | ||||
| 
 | ||||
| 	key := encryptionKeyToBytes(secret, salt) | ||||
| 	block, err := aes.NewCipher(key) | ||||
| 	if err != nil { | ||||
| 		log.Fatal(4, err.Error()) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	// The IV needs to be unique, but not secure. Therefore it's common to
 | ||||
|  | @ -51,13 +50,13 @@ func Encrypt(payload []byte, secret string) []byte { | |||
| 	copy(ciphertext[:saltLength], []byte(salt)) | ||||
| 	iv := ciphertext[saltLength : saltLength+aes.BlockSize] | ||||
| 	if _, err := io.ReadFull(rand.Reader, iv); err != nil { | ||||
| 		log.Fatal(4, err.Error()) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	stream := cipher.NewCFBEncrypter(block, iv) | ||||
| 	stream.XORKeyStream(ciphertext[saltLength+aes.BlockSize:], payload) | ||||
| 
 | ||||
| 	return ciphertext | ||||
| 	return ciphertext, nil | ||||
| } | ||||
| 
 | ||||
| // Key needs to be 32bytes
 | ||||
|  |  | |||
|  | @ -18,9 +18,11 @@ func TestEncryption(t *testing.T) { | |||
| 	}) | ||||
| 
 | ||||
| 	Convey("When decrypting basic payload", t, func() { | ||||
| 		encrypted := Encrypt([]byte("grafana"), "1234") | ||||
| 		decrypted := Decrypt(encrypted, "1234") | ||||
| 		encrypted, encryptErr := Encrypt([]byte("grafana"), "1234") | ||||
| 		decrypted, decryptErr := Decrypt(encrypted, "1234") | ||||
| 
 | ||||
| 		So(encryptErr, ShouldBeNil) | ||||
| 		So(decryptErr, ShouldBeNil) | ||||
| 		So(string(decrypted), ShouldEqual, "grafana") | ||||
| 	}) | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,5 +1,9 @@ | |||
| package util | ||||
| 
 | ||||
| import ( | ||||
| 	"regexp" | ||||
| ) | ||||
| 
 | ||||
| func StringsFallback2(val1 string, val2 string) string { | ||||
| 	return stringsFallback(val1, val2) | ||||
| } | ||||
|  | @ -16,3 +20,11 @@ func stringsFallback(vals ...string) string { | |||
| 	} | ||||
| 	return "" | ||||
| } | ||||
| 
 | ||||
| func SplitString(str string) []string { | ||||
| 	if len(str) == 0 { | ||||
| 		return []string{} | ||||
| 	} | ||||
| 
 | ||||
| 	return regexp.MustCompile("[, ]+").Split(str, -1) | ||||
| } | ||||
|  |  | |||
|  | @ -13,3 +13,14 @@ func TestStringsUtil(t *testing.T) { | |||
| 		So(StringsFallback3("", "", "3"), ShouldEqual, "3") | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func TestSplitString(t *testing.T) { | ||||
| 	Convey("Splits strings correctly", t, func() { | ||||
| 		So(SplitString(""), ShouldResemble, []string{}) | ||||
| 		So(SplitString("test"), ShouldResemble, []string{"test"}) | ||||
| 		So(SplitString("test1 test2 test3"), ShouldResemble, []string{"test1", "test2", "test3"}) | ||||
| 		So(SplitString("test1,test2,test3"), ShouldResemble, []string{"test1", "test2", "test3"}) | ||||
| 		So(SplitString("test1, test2, test3"), ShouldResemble, []string{"test1", "test2", "test3"}) | ||||
| 		So(SplitString("test1 , test2 test3"), ShouldResemble, []string{"test1", "test2", "test3"}) | ||||
| 	}) | ||||
| } | ||||
|  |  | |||
|  | @ -92,7 +92,7 @@ export class VariableSrv { | |||
| 
 | ||||
|   addVariable(model) { | ||||
|     var variable = this.createVariableFromModel(model); | ||||
|     this.variables.push(this.createVariableFromModel(variable)); | ||||
|     this.variables.push(variable); | ||||
|     return variable; | ||||
|   } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue