Encryption: De-duplicate encryption code with extensible service (#52472)

* Encryption: De-duplicate encryption code with extensible service

* Fix Wire injections

* Fix tests

* Register reload handler
This commit is contained in:
Joan López de la Franca Beltran
2022-08-02 15:08:09 +02:00
committed by GitHub
parent 9c6aab3bc9
commit 28e27e1365
41 changed files with 809 additions and 367 deletions

View File

@@ -12,6 +12,8 @@ import (
"github.com/grafana/grafana/pkg/infra/localcache" "github.com/grafana/grafana/pkg/infra/localcache"
"github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/infra/usagestats" "github.com/grafana/grafana/pkg/infra/usagestats"
"github.com/grafana/grafana/pkg/services/encryption"
encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/hooks" "github.com/grafana/grafana/pkg/services/hooks"
"github.com/grafana/grafana/pkg/services/secrets" "github.com/grafana/grafana/pkg/services/secrets"
@@ -34,6 +36,8 @@ var wireSet = wire.NewSet(
sqlstore.ProvideService, sqlstore.ProvideService,
wire.InterfaceValue(new(usagestats.Service), noOpUsageStats{}), wire.InterfaceValue(new(usagestats.Service), noOpUsageStats{}),
wire.InterfaceValue(new(routing.RouteRegister), noOpRouteRegister{}), wire.InterfaceValue(new(routing.RouteRegister), noOpRouteRegister{}),
encryptionservice.ProvideEncryptionService,
wire.Bind(new(encryption.Internal), new(*encryptionservice.Service)),
secretsDatabase.ProvideSecretsStore, secretsDatabase.ProvideSecretsStore,
wire.Bind(new(secrets.Store), new(*secretsDatabase.SecretsStoreImpl)), wire.Bind(new(secrets.Store), new(*secretsDatabase.SecretsStoreImpl)),
secretsManager.ProvideSecretsService, secretsManager.ProvideSecretsService,

View File

@@ -8,7 +8,7 @@ import (
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/registry" "github.com/grafana/grafana/pkg/registry"
"github.com/grafana/grafana/pkg/services/encryption" "github.com/grafana/grafana/pkg/services/encryption"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionprovider "github.com/grafana/grafana/pkg/services/encryption/provider"
"github.com/grafana/grafana/pkg/services/kmsproviders" "github.com/grafana/grafana/pkg/services/kmsproviders"
"github.com/grafana/grafana/pkg/services/kmsproviders/osskmsproviders" "github.com/grafana/grafana/pkg/services/kmsproviders/osskmsproviders"
"github.com/grafana/grafana/pkg/services/licensing" "github.com/grafana/grafana/pkg/services/licensing"
@@ -26,6 +26,6 @@ var wireExtsSet = wire.NewSet(
wire.Bind(new(setting.Provider), new(*setting.OSSImpl)), wire.Bind(new(setting.Provider), new(*setting.OSSImpl)),
osskmsproviders.ProvideService, osskmsproviders.ProvideService,
wire.Bind(new(kmsproviders.Service), new(osskmsproviders.Service)), wire.Bind(new(kmsproviders.Service), new(osskmsproviders.Service)),
ossencryption.ProvideService, encryptionprovider.ProvideEncryptionProvider,
wire.Bind(new(encryption.Internal), new(*ossencryption.Service)), wire.Bind(new(encryption.Provider), new(encryptionprovider.Provider)),
) )

View File

@@ -59,6 +59,8 @@ import (
"github.com/grafana/grafana/pkg/services/datasourceproxy" "github.com/grafana/grafana/pkg/services/datasourceproxy"
"github.com/grafana/grafana/pkg/services/datasources" "github.com/grafana/grafana/pkg/services/datasources"
datasourceservice "github.com/grafana/grafana/pkg/services/datasources/service" datasourceservice "github.com/grafana/grafana/pkg/services/datasources/service"
"github.com/grafana/grafana/pkg/services/encryption"
encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/services/export" "github.com/grafana/grafana/pkg/services/export"
"github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/guardian" "github.com/grafana/grafana/pkg/services/guardian"
@@ -231,6 +233,8 @@ var wireBasicSet = wire.NewSet(
graphite.ProvideService, graphite.ProvideService,
prometheus.ProvideService, prometheus.ProvideService,
elasticsearch.ProvideService, elasticsearch.ProvideService,
encryptionservice.ProvideEncryptionService,
wire.Bind(new(encryption.Internal), new(*encryptionservice.Service)),
secretsManager.ProvideSecretsService, secretsManager.ProvideSecretsService,
wire.Bind(new(secrets.Service), new(*secretsManager.SecretsService)), wire.Bind(new(secrets.Service), new(*secretsManager.SecretsService)),
secretsDatabase.ProvideSecretsStore, secretsDatabase.ProvideSecretsStore,

View File

@@ -21,7 +21,7 @@ import (
"github.com/grafana/grafana/pkg/services/datasources/permissions" "github.com/grafana/grafana/pkg/services/datasources/permissions"
datasourceservice "github.com/grafana/grafana/pkg/services/datasources/service" datasourceservice "github.com/grafana/grafana/pkg/services/datasources/service"
"github.com/grafana/grafana/pkg/services/encryption" "github.com/grafana/grafana/pkg/services/encryption"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionprovider "github.com/grafana/grafana/pkg/services/encryption/provider"
"github.com/grafana/grafana/pkg/services/kmsproviders" "github.com/grafana/grafana/pkg/services/kmsproviders"
"github.com/grafana/grafana/pkg/services/kmsproviders/osskmsproviders" "github.com/grafana/grafana/pkg/services/kmsproviders/osskmsproviders"
"github.com/grafana/grafana/pkg/services/ldap" "github.com/grafana/grafana/pkg/services/ldap"
@@ -63,8 +63,8 @@ var wireExtsBasicSet = wire.NewSet(
wire.Bind(new(registry.DatabaseMigrator), new(*migrations.OSSMigrations)), wire.Bind(new(registry.DatabaseMigrator), new(*migrations.OSSMigrations)),
authinfoservice.ProvideOSSUserProtectionService, authinfoservice.ProvideOSSUserProtectionService,
wire.Bind(new(login.UserProtectionService), new(*authinfoservice.OSSUserProtectionImpl)), wire.Bind(new(login.UserProtectionService), new(*authinfoservice.OSSUserProtectionImpl)),
ossencryption.ProvideService, encryptionprovider.ProvideEncryptionProvider,
wire.Bind(new(encryption.Internal), new(*ossencryption.Service)), wire.Bind(new(encryption.Provider), new(encryptionprovider.Provider)),
filters.ProvideOSSSearchUserFilter, filters.ProvideOSSSearchUserFilter,
wire.Bind(new(models.SearchUserFilter), new(*filters.OSSSearchUserFilter)), wire.Bind(new(models.SearchUserFilter), new(*filters.OSSSearchUserFilter)),
searchusers.ProvideUsersService, searchusers.ProvideUsersService,

View File

@@ -11,9 +11,9 @@ import (
"github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/infra/usagestats" "github.com/grafana/grafana/pkg/infra/usagestats"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionprovider "github.com/grafana/grafana/pkg/services/encryption/provider"
encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@@ -21,9 +21,18 @@ func TestIntegrationEngineTimeouts(t *testing.T) {
if testing.Short() { if testing.Short() {
t.Skip("skipping integration test") t.Skip("skipping integration test")
} }
usMock := &usagestats.UsageStatsMock{T: t} usMock := &usagestats.UsageStatsMock{T: t}
encProvider := encryptionprovider.ProvideEncryptionProvider()
cfg := setting.NewCfg()
settings := &setting.OSSImpl{Cfg: cfg}
encService, err := encryptionservice.ProvideEncryptionService(encProvider, usMock, settings)
require.NoError(t, err)
tracer := tracing.InitializeTracerForTest() tracer := tracing.InitializeTracerForTest()
engine := ProvideAlertEngine(nil, nil, nil, usMock, ossencryption.ProvideService(), nil, tracer, nil, setting.NewCfg(), nil, nil) engine := ProvideAlertEngine(nil, nil, nil, usMock, encService, nil, tracer, nil, cfg, nil, nil)
setting.AlertingNotificationTimeout = 30 * time.Second setting.AlertingNotificationTimeout = 30 * time.Second
setting.AlertingMaxAttempts = 3 setting.AlertingMaxAttempts = 3
engine.resultHandler = &FakeResultHandler{} engine.resultHandler = &FakeResultHandler{}

View File

@@ -7,15 +7,15 @@ import (
"testing" "testing"
"time" "time"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/infra/usagestats" "github.com/grafana/grafana/pkg/infra/usagestats"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources" "github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionprovider "github.com/grafana/grafana/pkg/services/encryption/provider"
encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/require"
) )
type FakeEvalHandler struct { type FakeEvalHandler struct {
@@ -101,10 +101,17 @@ func (a *AlertStoreMock) SetAlertState(_ context.Context, _ *models.SetAlertStat
func TestEngineProcessJob(t *testing.T) { func TestEngineProcessJob(t *testing.T) {
usMock := &usagestats.UsageStatsMock{T: t} usMock := &usagestats.UsageStatsMock{T: t}
encProvider := encryptionprovider.ProvideEncryptionProvider()
cfg := setting.NewCfg()
settings := &setting.OSSImpl{Cfg: cfg}
encService, err := encryptionservice.ProvideEncryptionService(encProvider, usMock, settings)
require.NoError(t, err)
tracer := tracing.InitializeTracerForTest() tracer := tracing.InitializeTracerForTest()
store := &AlertStoreMock{} store := &AlertStoreMock{}
engine := ProvideAlertEngine(nil, nil, nil, usMock, ossencryption.ProvideService(), nil, tracer, store, setting.NewCfg(), nil, nil) engine := ProvideAlertEngine(nil, nil, nil, usMock, encService, nil, tracer, store, cfg, nil, nil)
setting.AlertingEvaluationTimeout = 30 * time.Second setting.AlertingEvaluationTimeout = 30 * time.Second
setting.AlertingNotificationTimeout = 30 * time.Second setting.AlertingNotificationTimeout = 30 * time.Second
setting.AlertingMaxAttempts = 3 setting.AlertingMaxAttempts = 3

View File

@@ -8,7 +8,7 @@ import (
"github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting" "github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/services/validations" "github.com/grafana/grafana/pkg/services/validations"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@@ -81,6 +81,8 @@ func TestWhenAlertManagerShouldNotify(t *testing.T) {
//nolint:goconst //nolint:goconst
func TestAlertmanagerNotifier(t *testing.T) { func TestAlertmanagerNotifier(t *testing.T) {
encryptionService := encryptionservice.SetupTestService(t)
t.Run("Parsing alert notification from settings", func(t *testing.T) { t.Run("Parsing alert notification from settings", func(t *testing.T) {
t.Run("empty settings should return error", func(t *testing.T) { t.Run("empty settings should return error", func(t *testing.T) {
json := `{ }` json := `{ }`
@@ -92,7 +94,7 @@ func TestAlertmanagerNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewAlertmanagerNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) _, err := NewAlertmanagerNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@@ -106,7 +108,7 @@ func TestAlertmanagerNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewAlertmanagerNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewAlertmanagerNotifier(model, encryptionService.GetDecryptedValue, nil)
alertmanagerNotifier := not.(*AlertmanagerNotifier) alertmanagerNotifier := not.(*AlertmanagerNotifier)
require.NoError(t, err) require.NoError(t, err)
@@ -125,7 +127,7 @@ func TestAlertmanagerNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewAlertmanagerNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewAlertmanagerNotifier(model, encryptionService.GetDecryptedValue, nil)
alertmanagerNotifier := not.(*AlertmanagerNotifier) alertmanagerNotifier := not.(*AlertmanagerNotifier)
require.NoError(t, err) require.NoError(t, err)

View File

@@ -7,13 +7,15 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting" "github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/services/validations" "github.com/grafana/grafana/pkg/services/validations"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestDingDingNotifier(t *testing.T) { func TestDingDingNotifier(t *testing.T) {
encryptionService := encryptionservice.SetupTestService(t)
t.Run("empty settings should return error", func(t *testing.T) { t.Run("empty settings should return error", func(t *testing.T) {
json := `{ }` json := `{ }`
@@ -24,7 +26,7 @@ func TestDingDingNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := newDingDingNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) _, err := newDingDingNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
t.Run("settings should trigger incident", func(t *testing.T) { t.Run("settings should trigger incident", func(t *testing.T) {
@@ -37,7 +39,7 @@ func TestDingDingNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := newDingDingNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := newDingDingNotifier(model, encryptionService.GetDecryptedValue, nil)
notifier := not.(*DingDingNotifier) notifier := not.(*DingDingNotifier)
require.Nil(t, err) require.Nil(t, err)

View File

@@ -5,12 +5,14 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestDiscordNotifier(t *testing.T) { func TestDiscordNotifier(t *testing.T) {
encryptionService := encryptionservice.SetupTestService(t)
t.Run("Parsing alert notification from settings", func(t *testing.T) { t.Run("Parsing alert notification from settings", func(t *testing.T) {
t.Run("empty settings should return error", func(t *testing.T) { t.Run("empty settings should return error", func(t *testing.T) {
json := `{ }` json := `{ }`
@@ -22,7 +24,7 @@ func TestDiscordNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := newDiscordNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) _, err := newDiscordNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@@ -41,7 +43,7 @@ func TestDiscordNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := newDiscordNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := newDiscordNotifier(model, encryptionService.GetDecryptedValue, nil)
discordNotifier := not.(*DiscordNotifier) discordNotifier := not.(*DiscordNotifier)
require.Nil(t, err) require.Nil(t, err)

View File

@@ -5,12 +5,14 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestEmailNotifier(t *testing.T) { func TestEmailNotifier(t *testing.T) {
encryptionService := encryptionservice.SetupTestService(t)
t.Run("Parsing alert notification from settings", func(t *testing.T) { t.Run("Parsing alert notification from settings", func(t *testing.T) {
t.Run("empty settings should return error", func(t *testing.T) { t.Run("empty settings should return error", func(t *testing.T) {
json := `{ }` json := `{ }`
@@ -22,7 +24,7 @@ func TestEmailNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewEmailNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) _, err := NewEmailNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@@ -39,7 +41,7 @@ func TestEmailNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewEmailNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewEmailNotifier(model, encryptionService.GetDecryptedValue, nil)
emailNotifier := not.(*EmailNotifier) emailNotifier := not.(*EmailNotifier)
require.Nil(t, err) require.Nil(t, err)
@@ -63,7 +65,7 @@ func TestEmailNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewEmailNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewEmailNotifier(model, encryptionService.GetDecryptedValue, nil)
emailNotifier := not.(*EmailNotifier) emailNotifier := not.(*EmailNotifier)
require.Nil(t, err) require.Nil(t, err)

View File

@@ -5,12 +5,14 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestGoogleChatNotifier(t *testing.T) { func TestGoogleChatNotifier(t *testing.T) {
encryptionService := encryptionservice.SetupTestService(t)
t.Run("Parsing alert notification from settings", func(t *testing.T) { t.Run("Parsing alert notification from settings", func(t *testing.T) {
t.Run("empty settings should return error", func(t *testing.T) { t.Run("empty settings should return error", func(t *testing.T) {
json := `{ }` json := `{ }`
@@ -22,7 +24,7 @@ func TestGoogleChatNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := newGoogleChatNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) _, err := newGoogleChatNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@@ -39,7 +41,7 @@ func TestGoogleChatNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := newGoogleChatNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := newGoogleChatNotifier(model, encryptionService.GetDecryptedValue, nil)
webhookNotifier := not.(*GoogleChatNotifier) webhookNotifier := not.(*GoogleChatNotifier)
require.Nil(t, err) require.Nil(t, err)

View File

@@ -5,13 +5,15 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
//nolint:goconst //nolint:goconst
func TestHipChatNotifier(t *testing.T) { func TestHipChatNotifier(t *testing.T) {
encryptionService := encryptionservice.SetupTestService(t)
t.Run("Parsing alert notification from settings", func(t *testing.T) { t.Run("Parsing alert notification from settings", func(t *testing.T) {
t.Run("empty settings should return error", func(t *testing.T) { t.Run("empty settings should return error", func(t *testing.T) {
json := `{ }` json := `{ }`
@@ -23,7 +25,7 @@ func TestHipChatNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewHipChatNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) _, err := NewHipChatNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@@ -39,7 +41,7 @@ func TestHipChatNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewHipChatNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewHipChatNotifier(model, encryptionService.GetDecryptedValue, nil)
hipchatNotifier := not.(*HipChatNotifier) hipchatNotifier := not.(*HipChatNotifier)
require.Nil(t, err) require.Nil(t, err)
@@ -65,7 +67,7 @@ func TestHipChatNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewHipChatNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewHipChatNotifier(model, encryptionService.GetDecryptedValue, nil)
hipchatNotifier := not.(*HipChatNotifier) hipchatNotifier := not.(*HipChatNotifier)
require.Nil(t, err) require.Nil(t, err)

View File

@@ -5,12 +5,14 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestKafkaNotifier(t *testing.T) { func TestKafkaNotifier(t *testing.T) {
encryptionService := encryptionservice.SetupTestService(t)
t.Run("Parsing alert notification from settings", func(t *testing.T) { t.Run("Parsing alert notification from settings", func(t *testing.T) {
t.Run("empty settings should return error", func(t *testing.T) { t.Run("empty settings should return error", func(t *testing.T) {
json := `{ }` json := `{ }`
@@ -22,7 +24,7 @@ func TestKafkaNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewKafkaNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) _, err := NewKafkaNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@@ -40,7 +42,7 @@ func TestKafkaNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewKafkaNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewKafkaNotifier(model, encryptionService.GetDecryptedValue, nil)
kafkaNotifier := not.(*KafkaNotifier) kafkaNotifier := not.(*KafkaNotifier)
require.Nil(t, err) require.Nil(t, err)

View File

@@ -5,12 +5,14 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestLineNotifier(t *testing.T) { func TestLineNotifier(t *testing.T) {
encryptionService := encryptionservice.SetupTestService(t)
t.Run("empty settings should return error", func(t *testing.T) { t.Run("empty settings should return error", func(t *testing.T) {
json := `{ }` json := `{ }`
@@ -21,7 +23,7 @@ func TestLineNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewLINENotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) _, err := NewLINENotifier(model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
t.Run("settings should trigger incident", func(t *testing.T) { t.Run("settings should trigger incident", func(t *testing.T) {
@@ -36,7 +38,7 @@ func TestLineNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewLINENotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewLINENotifier(model, encryptionService.GetDecryptedValue, nil)
lineNotifier := not.(*LineNotifier) lineNotifier := not.(*LineNotifier)
require.Nil(t, err) require.Nil(t, err)

View File

@@ -9,7 +9,7 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting" "github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/services/notifications" "github.com/grafana/grafana/pkg/services/notifications"
"github.com/grafana/grafana/pkg/services/validations" "github.com/grafana/grafana/pkg/services/validations"
@@ -17,6 +17,8 @@ import (
) )
func TestOpsGenieNotifier(t *testing.T) { func TestOpsGenieNotifier(t *testing.T) {
encryptionService := encryptionservice.SetupTestService(t)
t.Run("Parsing alert notification from settings", func(t *testing.T) { t.Run("Parsing alert notification from settings", func(t *testing.T) {
t.Run("empty settings should return error", func(t *testing.T) { t.Run("empty settings should return error", func(t *testing.T) {
json := `{ }` json := `{ }`
@@ -28,7 +30,7 @@ func TestOpsGenieNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewOpsGenieNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) _, err := NewOpsGenieNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@@ -45,7 +47,7 @@ func TestOpsGenieNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewOpsGenieNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewOpsGenieNotifier(model, encryptionService.GetDecryptedValue, nil)
opsgenieNotifier := not.(*OpsGenieNotifier) opsgenieNotifier := not.(*OpsGenieNotifier)
require.Nil(t, err) require.Nil(t, err)
@@ -69,7 +71,7 @@ func TestOpsGenieNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewOpsGenieNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) _, err := NewOpsGenieNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
require.Equal(t, reflect.TypeOf(err), reflect.TypeOf(alerting.ValidationError{})) require.Equal(t, reflect.TypeOf(err), reflect.TypeOf(alerting.ValidationError{}))
require.True(t, strings.HasSuffix(err.Error(), "Invalid value for sendTagsAs: \"not_a_valid_value\"")) require.True(t, strings.HasSuffix(err.Error(), "Invalid value for sendTagsAs: \"not_a_valid_value\""))
@@ -93,7 +95,7 @@ func TestOpsGenieNotifier(t *testing.T) {
} }
notificationService := notifications.MockNotificationService() notificationService := notifications.MockNotificationService()
notifier, notifierErr := NewOpsGenieNotifier(model, ossencryption.ProvideService().GetDecryptedValue, notificationService) // unhandled error notifier, notifierErr := NewOpsGenieNotifier(model, encryptionService.GetDecryptedValue, notificationService) // unhandled error
opsgenieNotifier := notifier.(*OpsGenieNotifier) opsgenieNotifier := notifier.(*OpsGenieNotifier)
@@ -142,7 +144,7 @@ func TestOpsGenieNotifier(t *testing.T) {
} }
notificationService := notifications.MockNotificationService() notificationService := notifications.MockNotificationService()
notifier, notifierErr := NewOpsGenieNotifier(model, ossencryption.ProvideService().GetDecryptedValue, notificationService) // unhandled error notifier, notifierErr := NewOpsGenieNotifier(model, encryptionService.GetDecryptedValue, notificationService) // unhandled error
opsgenieNotifier := notifier.(*OpsGenieNotifier) opsgenieNotifier := notifier.(*OpsGenieNotifier)
@@ -191,7 +193,7 @@ func TestOpsGenieNotifier(t *testing.T) {
} }
notificationService := notifications.MockNotificationService() notificationService := notifications.MockNotificationService()
notifier, notifierErr := NewOpsGenieNotifier(model, ossencryption.ProvideService().GetDecryptedValue, notificationService) // unhandled error notifier, notifierErr := NewOpsGenieNotifier(model, encryptionService.GetDecryptedValue, notificationService) // unhandled error
opsgenieNotifier := notifier.(*OpsGenieNotifier) opsgenieNotifier := notifier.(*OpsGenieNotifier)

View File

@@ -11,7 +11,7 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting" "github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/services/validations" "github.com/grafana/grafana/pkg/services/validations"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@@ -28,6 +28,8 @@ func presenceComparer(a, b string) bool {
} }
func TestPagerdutyNotifier(t *testing.T) { func TestPagerdutyNotifier(t *testing.T) {
encryptionService := encryptionservice.SetupTestService(t)
t.Run("empty settings should return error", func(t *testing.T) { t.Run("empty settings should return error", func(t *testing.T) {
json := `{ }` json := `{ }`
@@ -40,7 +42,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err = NewPagerdutyNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) _, err = NewPagerdutyNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@@ -56,7 +58,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewPagerdutyNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewPagerdutyNotifier(model, encryptionService.GetDecryptedValue, nil)
pagerdutyNotifier := not.(*PagerdutyNotifier) pagerdutyNotifier := not.(*PagerdutyNotifier)
require.Nil(t, err) require.Nil(t, err)
@@ -79,7 +81,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewPagerdutyNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewPagerdutyNotifier(model, encryptionService.GetDecryptedValue, nil)
pagerdutyNotifier := not.(*PagerdutyNotifier) pagerdutyNotifier := not.(*PagerdutyNotifier)
require.Nil(t, err) require.Nil(t, err)
@@ -106,7 +108,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewPagerdutyNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewPagerdutyNotifier(model, encryptionService.GetDecryptedValue, nil)
pagerdutyNotifier := not.(*PagerdutyNotifier) pagerdutyNotifier := not.(*PagerdutyNotifier)
require.Nil(t, err) require.Nil(t, err)
@@ -131,7 +133,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewPagerdutyNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewPagerdutyNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Nil(t, err) require.Nil(t, err)
pagerdutyNotifier := not.(*PagerdutyNotifier) pagerdutyNotifier := not.(*PagerdutyNotifier)
@@ -188,7 +190,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewPagerdutyNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewPagerdutyNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Nil(t, err) require.Nil(t, err)
pagerdutyNotifier := not.(*PagerdutyNotifier) pagerdutyNotifier := not.(*PagerdutyNotifier)
@@ -245,7 +247,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewPagerdutyNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewPagerdutyNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Nil(t, err) require.Nil(t, err)
pagerdutyNotifier := not.(*PagerdutyNotifier) pagerdutyNotifier := not.(*PagerdutyNotifier)
@@ -315,7 +317,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewPagerdutyNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewPagerdutyNotifier(model, encryptionService.GetDecryptedValue, nil)
require.NoError(t, err) require.NoError(t, err)
pagerdutyNotifier := not.(*PagerdutyNotifier) pagerdutyNotifier := not.(*PagerdutyNotifier)
@@ -395,7 +397,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewPagerdutyNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewPagerdutyNotifier(model, encryptionService.GetDecryptedValue, nil)
require.NoError(t, err) require.NoError(t, err)
pagerdutyNotifier := not.(*PagerdutyNotifier) pagerdutyNotifier := not.(*PagerdutyNotifier)
@@ -474,7 +476,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewPagerdutyNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewPagerdutyNotifier(model, encryptionService.GetDecryptedValue, nil)
require.NoError(t, err) require.NoError(t, err)
pagerdutyNotifier := not.(*PagerdutyNotifier) pagerdutyNotifier := not.(*PagerdutyNotifier)

View File

@@ -8,13 +8,15 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting" "github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/services/validations" "github.com/grafana/grafana/pkg/services/validations"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestPushoverNotifier(t *testing.T) { func TestPushoverNotifier(t *testing.T) {
encryptionService := encryptionservice.SetupTestService(t)
t.Run("Parsing alert notification from settings", func(t *testing.T) { t.Run("Parsing alert notification from settings", func(t *testing.T) {
t.Run("empty settings should return error", func(t *testing.T) { t.Run("empty settings should return error", func(t *testing.T) {
json := `{ }` json := `{ }`
@@ -26,7 +28,7 @@ func TestPushoverNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewPushoverNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) _, err := NewPushoverNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@@ -48,7 +50,7 @@ func TestPushoverNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewPushoverNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewPushoverNotifier(model, encryptionService.GetDecryptedValue, nil)
pushoverNotifier := not.(*PushoverNotifier) pushoverNotifier := not.(*PushoverNotifier)
require.Nil(t, err) require.Nil(t, err)

View File

@@ -5,12 +5,14 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestSensuNotifier(t *testing.T) { func TestSensuNotifier(t *testing.T) {
encryptionService := encryptionservice.SetupTestService(t)
t.Run("Parsing alert notification from settings", func(t *testing.T) { t.Run("Parsing alert notification from settings", func(t *testing.T) {
t.Run("empty settings should return error", func(t *testing.T) { t.Run("empty settings should return error", func(t *testing.T) {
json := `{ }` json := `{ }`
@@ -22,7 +24,7 @@ func TestSensuNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewSensuNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) _, err := NewSensuNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@@ -41,7 +43,7 @@ func TestSensuNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewSensuNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewSensuNotifier(model, encryptionService.GetDecryptedValue, nil)
sensuNotifier := not.(*SensuNotifier) sensuNotifier := not.(*SensuNotifier)
require.Nil(t, err) require.Nil(t, err)

View File

@@ -5,7 +5,8 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@@ -21,7 +22,9 @@ func TestSensuGoNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err = NewSensuGoNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) encryptionService := encryptionservice.SetupTestService(t)
_, err = NewSensuGoNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
json = ` json = `
@@ -42,7 +45,7 @@ func TestSensuGoNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewSensuGoNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewSensuGoNotifier(model, encryptionService.GetDecryptedValue, nil)
require.NoError(t, err) require.NoError(t, err)
sensuGoNotifier := not.(*SensuGoNotifier) sensuGoNotifier := not.(*SensuGoNotifier)

View File

@@ -9,13 +9,15 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestSlackNotifier(t *testing.T) { func TestSlackNotifier(t *testing.T) {
encryptionService := encryptionservice.SetupTestService(t)
t.Run("empty settings should return error", func(t *testing.T) { t.Run("empty settings should return error", func(t *testing.T) {
json := `{ }` json := `{ }`
@@ -27,7 +29,7 @@ func TestSlackNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err = NewSlackNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) _, err = NewSlackNotifier(model, encryptionService.GetDecryptedValue, nil)
assert.EqualError(t, err, "alert validation error: recipient must be specified when using the Slack chat API") assert.EqualError(t, err, "alert validation error: recipient must be specified when using the Slack chat API")
}) })
@@ -45,7 +47,7 @@ func TestSlackNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewSlackNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewSlackNotifier(model, encryptionService.GetDecryptedValue, nil)
require.NoError(t, err) require.NoError(t, err)
slackNotifier := not.(*SlackNotifier) slackNotifier := not.(*SlackNotifier)
assert.Equal(t, "ops", slackNotifier.Name) assert.Equal(t, "ops", slackNotifier.Name)
@@ -83,7 +85,7 @@ func TestSlackNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewSlackNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewSlackNotifier(model, encryptionService.GetDecryptedValue, nil)
require.NoError(t, err) require.NoError(t, err)
slackNotifier := not.(*SlackNotifier) slackNotifier := not.(*SlackNotifier)
assert.Equal(t, "ops", slackNotifier.Name) assert.Equal(t, "ops", slackNotifier.Name)
@@ -116,7 +118,7 @@ func TestSlackNotifier(t *testing.T) {
settingsJSON, err := simplejson.NewJson([]byte(json)) settingsJSON, err := simplejson.NewJson([]byte(json))
require.NoError(t, err) require.NoError(t, err)
encryptionService := ossencryption.ProvideService() encryptionService := encryptionService
securedSettingsJSON, err := encryptionService.EncryptJsonData( securedSettingsJSON, err := encryptionService.EncryptJsonData(
context.Background(), context.Background(),
map[string]string{ map[string]string{
@@ -131,7 +133,7 @@ func TestSlackNotifier(t *testing.T) {
SecureSettings: securedSettingsJSON, SecureSettings: securedSettingsJSON,
} }
not, err := NewSlackNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewSlackNotifier(model, encryptionService.GetDecryptedValue, nil)
require.NoError(t, err) require.NoError(t, err)
slackNotifier := not.(*SlackNotifier) slackNotifier := not.(*SlackNotifier)
assert.Equal(t, "ops", slackNotifier.Name) assert.Equal(t, "ops", slackNotifier.Name)
@@ -162,7 +164,7 @@ func TestSlackNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewSlackNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewSlackNotifier(model, encryptionService.GetDecryptedValue, nil)
require.NoError(t, err) require.NoError(t, err)
slackNotifier := not.(*SlackNotifier) slackNotifier := not.(*SlackNotifier)
assert.Equal(t, "1ABCDE", slackNotifier.recipient) assert.Equal(t, "1ABCDE", slackNotifier.recipient)
@@ -253,7 +255,9 @@ func TestSendSlackRequest(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewSlackNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) encryptionService := encryptionservice.SetupTestService(t)
not, err := NewSlackNotifier(model, encryptionService.GetDecryptedValue, nil)
require.NoError(t, err) require.NoError(t, err)
slackNotifier := not.(*SlackNotifier) slackNotifier := not.(*SlackNotifier)

View File

@@ -5,12 +5,14 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestTeamsNotifier(t *testing.T) { func TestTeamsNotifier(t *testing.T) {
encryptionService := encryptionservice.SetupTestService(t)
t.Run("Parsing alert notification from settings", func(t *testing.T) { t.Run("Parsing alert notification from settings", func(t *testing.T) {
t.Run("empty settings should return error", func(t *testing.T) { t.Run("empty settings should return error", func(t *testing.T) {
json := `{ }` json := `{ }`
@@ -22,7 +24,7 @@ func TestTeamsNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewTeamsNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) _, err := NewTeamsNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@@ -39,7 +41,7 @@ func TestTeamsNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewTeamsNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewTeamsNotifier(model, encryptionService.GetDecryptedValue, nil)
teamsNotifier := not.(*TeamsNotifier) teamsNotifier := not.(*TeamsNotifier)
require.Nil(t, err) require.Nil(t, err)
@@ -61,7 +63,7 @@ func TestTeamsNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewTeamsNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewTeamsNotifier(model, encryptionService.GetDecryptedValue, nil)
teamsNotifier := not.(*TeamsNotifier) teamsNotifier := not.(*TeamsNotifier)
require.Nil(t, err) require.Nil(t, err)

View File

@@ -7,13 +7,15 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting" "github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/services/validations" "github.com/grafana/grafana/pkg/services/validations"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestTelegramNotifier(t *testing.T) { func TestTelegramNotifier(t *testing.T) {
encryptionService := encryptionservice.SetupTestService(t)
t.Run("Parsing alert notification from settings", func(t *testing.T) { t.Run("Parsing alert notification from settings", func(t *testing.T) {
t.Run("empty settings should return error", func(t *testing.T) { t.Run("empty settings should return error", func(t *testing.T) {
json := `{ }` json := `{ }`
@@ -25,7 +27,7 @@ func TestTelegramNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewTelegramNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) _, err := NewTelegramNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@@ -43,7 +45,7 @@ func TestTelegramNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewTelegramNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewTelegramNotifier(model, encryptionService.GetDecryptedValue, nil)
telegramNotifier := not.(*TelegramNotifier) telegramNotifier := not.(*TelegramNotifier)
require.Nil(t, err) require.Nil(t, err)

View File

@@ -7,12 +7,14 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting" "github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestThreemaNotifier(t *testing.T) { func TestThreemaNotifier(t *testing.T) {
encryptionService := encryptionservice.SetupTestService(t)
t.Run("Parsing alert notification from settings", func(t *testing.T) { t.Run("Parsing alert notification from settings", func(t *testing.T) {
t.Run("empty settings should return error", func(t *testing.T) { t.Run("empty settings should return error", func(t *testing.T) {
json := `{ }` json := `{ }`
@@ -24,7 +26,7 @@ func TestThreemaNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewThreemaNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) _, err := NewThreemaNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@@ -43,7 +45,7 @@ func TestThreemaNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewThreemaNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewThreemaNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Nil(t, err) require.Nil(t, err)
threemaNotifier := not.(*ThreemaNotifier) threemaNotifier := not.(*ThreemaNotifier)
@@ -70,7 +72,7 @@ func TestThreemaNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewThreemaNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewThreemaNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Nil(t, not) require.Nil(t, not)
var valErr alerting.ValidationError var valErr alerting.ValidationError
require.True(t, errors.As(err, &valErr)) require.True(t, errors.As(err, &valErr))
@@ -92,7 +94,7 @@ func TestThreemaNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewThreemaNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewThreemaNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Nil(t, not) require.Nil(t, not)
var valErr alerting.ValidationError var valErr alerting.ValidationError
require.True(t, errors.As(err, &valErr)) require.True(t, errors.As(err, &valErr))
@@ -114,7 +116,7 @@ func TestThreemaNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewThreemaNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewThreemaNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Nil(t, not) require.Nil(t, not)
var valErr alerting.ValidationError var valErr alerting.ValidationError
require.True(t, errors.As(err, &valErr)) require.True(t, errors.As(err, &valErr))

View File

@@ -9,7 +9,7 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting" "github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/services/validations" "github.com/grafana/grafana/pkg/services/validations"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@@ -25,6 +25,8 @@ func presenceComparerInt(a, b int64) bool {
return a == b return a == b
} }
func TestVictoropsNotifier(t *testing.T) { func TestVictoropsNotifier(t *testing.T) {
encryptionService := encryptionservice.SetupTestService(t)
t.Run("Parsing alert notification from settings", func(t *testing.T) { t.Run("Parsing alert notification from settings", func(t *testing.T) {
t.Run("empty settings should return error", func(t *testing.T) { t.Run("empty settings should return error", func(t *testing.T) {
json := `{ }` json := `{ }`
@@ -36,7 +38,7 @@ func TestVictoropsNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewVictoropsNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) _, err := NewVictoropsNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@@ -53,7 +55,7 @@ func TestVictoropsNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewVictoropsNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewVictoropsNotifier(model, encryptionService.GetDecryptedValue, nil)
victoropsNotifier := not.(*VictoropsNotifier) victoropsNotifier := not.(*VictoropsNotifier)
require.Nil(t, err) require.Nil(t, err)
@@ -77,7 +79,7 @@ func TestVictoropsNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewVictoropsNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewVictoropsNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Nil(t, err) require.Nil(t, err)
victoropsNotifier := not.(*VictoropsNotifier) victoropsNotifier := not.(*VictoropsNotifier)
@@ -125,7 +127,7 @@ func TestVictoropsNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewVictoropsNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewVictoropsNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Nil(t, err) require.Nil(t, err)
victoropsNotifier := not.(*VictoropsNotifier) victoropsNotifier := not.(*VictoropsNotifier)

View File

@@ -5,12 +5,15 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestWebhookNotifier_parsingFromSettings(t *testing.T) { func TestWebhookNotifier_parsingFromSettings(t *testing.T) {
encryptionService := encryptionservice.SetupTestService(t)
t.Run("Empty settings should cause error", func(t *testing.T) { t.Run("Empty settings should cause error", func(t *testing.T) {
const json = `{}` const json = `{}`
@@ -22,7 +25,7 @@ func TestWebhookNotifier_parsingFromSettings(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err = NewWebHookNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) _, err = NewWebHookNotifier(model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@@ -37,7 +40,7 @@ func TestWebhookNotifier_parsingFromSettings(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewWebHookNotifier(model, ossencryption.ProvideService().GetDecryptedValue, nil) not, err := NewWebHookNotifier(model, encryptionService.GetDecryptedValue, nil)
require.NoError(t, err) require.NoError(t, err)
webhookNotifier := not.(*WebhookNotifier) webhookNotifier := not.(*WebhookNotifier)

View File

@@ -6,8 +6,10 @@ import (
"testing" "testing"
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/usagestats"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionprovider "github.com/grafana/grafana/pkg/services/encryption/provider"
encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/services/notifications" "github.com/grafana/grafana/pkg/services/notifications"
"github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
@@ -20,7 +22,15 @@ func TestService(t *testing.T) {
nType := "test" nType := "test"
registerTestNotifier(nType) registerTestNotifier(nType)
s := ProvideService(sqlStore, ossencryption.ProvideService(), nil) usMock := &usagestats.UsageStatsMock{T: t}
encProvider := encryptionprovider.ProvideEncryptionProvider()
settings := &setting.OSSImpl{Cfg: setting.NewCfg()}
encService, err := encryptionservice.ProvideEncryptionService(encProvider, usMock, settings)
require.NoError(t, err)
s := ProvideService(sqlStore, encService, nil)
origSecret := setting.SecretKey origSecret := setting.SecretKey
setting.SecretKey = "alert_notification_service_test" setting.SecretKey = "alert_notification_service_test"

View File

@@ -1,6 +1,18 @@
package encryption package encryption
import "context" import (
"context"
"crypto/sha256"
"golang.org/x/crypto/pbkdf2"
)
const (
SaltLength = 8
AesCfb = "aes-cfb"
AesGcm = "aes-gcm"
)
// Internal must not be used for general purpose encryption. // Internal must not be used for general purpose encryption.
// This service is used as an internal component for envelope encryption // This service is used as an internal component for envelope encryption
@@ -8,11 +20,29 @@ import "context"
// //
// Unless there is any specific reason, you must use secrets.Service instead. // Unless there is any specific reason, you must use secrets.Service instead.
type Internal interface { type Internal interface {
Encrypt(ctx context.Context, payload []byte, secret string) ([]byte, error) Cipher
Decrypt(ctx context.Context, payload []byte, secret string) ([]byte, error) Decipher
EncryptJsonData(ctx context.Context, kv map[string]string, secret string) (map[string][]byte, error) EncryptJsonData(ctx context.Context, kv map[string]string, secret string) (map[string][]byte, error)
DecryptJsonData(ctx context.Context, sjd map[string][]byte, secret string) (map[string]string, error) DecryptJsonData(ctx context.Context, sjd map[string][]byte, secret string) (map[string]string, error)
GetDecryptedValue(ctx context.Context, sjd map[string][]byte, key string, fallback string, secret string) string GetDecryptedValue(ctx context.Context, sjd map[string][]byte, key string, fallback string, secret string) string
} }
type Cipher interface {
Encrypt(ctx context.Context, payload []byte, secret string) ([]byte, error)
}
type Decipher interface {
Decrypt(ctx context.Context, payload []byte, secret string) ([]byte, error)
}
type Provider interface {
ProvideCiphers() map[string]Cipher
ProvideDeciphers() map[string]Decipher
}
// KeyToBytes key length needs to be 32 bytes
func KeyToBytes(secret, salt string) ([]byte, error) {
return pbkdf2.Key([]byte(secret), []byte(salt), 10000, 32, sha256.New), nil
}

View File

@@ -0,0 +1,22 @@
package encryption
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_KeyToBytes(t *testing.T) {
t.Run("with regular secret", func(t *testing.T) {
key, err := KeyToBytes("secret", "salt")
require.NoError(t, err)
assert.Len(t, key, 32)
})
t.Run("with very long secret", func(t *testing.T) {
key, err := KeyToBytes("a very long secret key that is larger then 32bytes", "salt")
require.NoError(t, err)
assert.Len(t, key, 32)
})
}

View File

@@ -1,180 +0,0 @@
package ossencryption
import (
"bytes"
"context"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"errors"
"fmt"
"io"
"github.com/grafana/grafana/pkg/util"
"golang.org/x/crypto/pbkdf2"
)
// Service must not be used for encryption,
// use secrets.Service implementing envelope encryption instead.
type Service struct{}
func ProvideService() *Service {
return &Service{}
}
const (
saltLength = 8
aesCfb = "aes-cfb"
encryptionAlgorithmDelimiter = '*'
)
func (s *Service) Decrypt(_ context.Context, payload []byte, secret string) ([]byte, error) {
alg, payload, err := deriveEncryptionAlgorithm(payload)
if err != nil {
return nil, err
}
if len(payload) < saltLength {
return nil, errors.New("unable to compute salt")
}
salt := payload[:saltLength]
key, err := encryptionKeyToBytes(secret, string(salt))
if err != nil {
return nil, err
}
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
switch alg {
case aesCfb:
return decryptCFB(block, payload)
default:
return nil, errors.New("unsupported encryption algorithm")
}
}
func deriveEncryptionAlgorithm(payload []byte) (string, []byte, error) {
if len(payload) == 0 {
return "", nil, fmt.Errorf("unable to derive encryption algorithm")
}
if payload[0] != encryptionAlgorithmDelimiter {
return aesCfb, payload, nil // backwards compatibility
}
payload = payload[1:]
algDelim := bytes.Index(payload, []byte{encryptionAlgorithmDelimiter})
if algDelim == -1 {
return aesCfb, payload, nil // backwards compatibility
}
algB64 := payload[:algDelim]
payload = payload[algDelim+1:]
alg := make([]byte, base64.RawStdEncoding.DecodedLen(len(algB64)))
_, err := base64.RawStdEncoding.Decode(alg, algB64)
if err != nil {
return "", nil, err
}
return string(alg), payload, nil
}
func decryptCFB(block cipher.Block, payload []byte) ([]byte, error) {
// 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 {
return nil, errors.New("payload too short")
}
iv := payload[saltLength : saltLength+aes.BlockSize]
payload = payload[saltLength+aes.BlockSize:]
payloadDst := make([]byte, len(payload))
stream := cipher.NewCFBDecrypter(block, iv)
// XORKeyStream can work in-place if the two arguments are the same.
stream.XORKeyStream(payloadDst, payload)
return payloadDst, nil
}
func (s *Service) Encrypt(_ context.Context, payload []byte, secret string) ([]byte, error) {
salt, err := util.GetRandomString(saltLength)
if err != nil {
return nil, err
}
key, err := encryptionKeyToBytes(secret, salt)
if err != nil {
return nil, err
}
block, err := aes.NewCipher(key)
if err != nil {
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.
ciphertext := make([]byte, saltLength+aes.BlockSize+len(payload))
copy(ciphertext[:saltLength], salt)
iv := ciphertext[saltLength : saltLength+aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return nil, err
}
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(ciphertext[saltLength+aes.BlockSize:], payload)
return ciphertext, nil
}
func (s *Service) EncryptJsonData(ctx context.Context, kv map[string]string, secret string) (map[string][]byte, error) {
encrypted := make(map[string][]byte)
for key, value := range kv {
encryptedData, err := s.Encrypt(ctx, []byte(value), secret)
if err != nil {
return nil, err
}
encrypted[key] = encryptedData
}
return encrypted, nil
}
func (s *Service) DecryptJsonData(ctx context.Context, sjd map[string][]byte, secret string) (map[string]string, error) {
decrypted := make(map[string]string)
for key, data := range sjd {
decryptedData, err := s.Decrypt(ctx, data, secret)
if err != nil {
return nil, err
}
decrypted[key] = string(decryptedData)
}
return decrypted, nil
}
func (s *Service) GetDecryptedValue(ctx context.Context, sjd map[string][]byte, key, fallback, secret string) string {
if value, ok := sjd[key]; ok {
decryptedData, err := s.Decrypt(ctx, value, secret)
if err != nil {
return fallback
}
return string(decryptedData)
}
return fallback
}
// Key needs to be 32bytes
func encryptionKeyToBytes(secret, salt string) ([]byte, error) {
return pbkdf2.Key([]byte(secret), []byte(salt), 10000, 32, sha256.New), nil
}

View File

@@ -1,68 +0,0 @@
package ossencryption
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestEncryption(t *testing.T) {
svc := Service{}
t.Run("getting encryption key", func(t *testing.T) {
key, err := encryptionKeyToBytes("secret", "salt")
require.NoError(t, err)
assert.Len(t, key, 32)
key, err = encryptionKeyToBytes("a very long secret key that is larger then 32bytes", "salt")
require.NoError(t, err)
assert.Len(t, key, 32)
})
t.Run("decrypting basic payload", func(t *testing.T) {
ctx := context.Background()
encrypted, err := svc.Encrypt(ctx, []byte("grafana"), "1234")
require.NoError(t, err)
decrypted, err := svc.Decrypt(ctx, encrypted, "1234")
require.NoError(t, err)
assert.Equal(t, []byte("grafana"), decrypted)
})
t.Run("decrypting empty payload should return error", func(t *testing.T) {
_, err := svc.Decrypt(context.Background(), []byte(""), "1234")
require.Error(t, err)
assert.Equal(t, "unable to derive encryption algorithm", err.Error())
})
t.Run("decrypting ciphertext with aes-gcm as encryption algorithm should return error", func(t *testing.T) {
// Raw slice of bytes that corresponds to the following ciphertext:
// - 'grafana' as payload
// - '1234' as secret
// - 'aes-gcm' as encryption algorithm
// With no encryption algorithm metadata.
ciphertext := []byte{42, 89, 87, 86, 122, 76, 87, 100, 106, 98, 81, 42, 48, 99, 55, 50, 51, 48, 83, 66, 20, 99, 47, 238, 61, 44, 129, 125, 14, 37, 162, 230, 47, 31, 104, 70, 144, 223, 26, 51, 180, 17, 76, 52, 36, 93, 17, 203, 99, 158, 219, 102, 74, 173, 74}
_, err := svc.Decrypt(context.Background(), ciphertext, "1234")
require.Error(t, err)
assert.Equal(t, "unsupported encryption algorithm", err.Error())
})
t.Run("decrypting ciphertext with aes-cfb as encryption algorithm do not fail", func(t *testing.T) {
// Raw slice of bytes that corresponds to the following ciphertext:
// - 'grafana' as payload
// - '1234' as secret
// - 'aes-cfb' as encryption algorithm
// With no encryption algorithm metadata.
ciphertext := []byte{42, 89, 87, 86, 122, 76, 87, 78, 109, 89, 103, 42, 73, 71, 50, 57, 121, 110, 90, 109, 115, 23, 237, 13, 130, 188, 151, 118, 98, 103, 80, 209, 79, 143, 22, 122, 44, 40, 102, 41, 136, 16, 27}
decrypted, err := svc.Decrypt(context.Background(), ciphertext, "1234")
require.NoError(t, err)
assert.Equal(t, []byte("grafana"), decrypted)
})
}

View File

@@ -0,0 +1,45 @@
package provider
import (
"context"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"io"
"github.com/grafana/grafana/pkg/services/encryption"
"github.com/grafana/grafana/pkg/util"
)
type aesCfbCipher struct{}
func (c aesCfbCipher) Encrypt(_ context.Context, payload []byte, secret string) ([]byte, error) {
salt, err := util.GetRandomString(encryption.SaltLength)
if err != nil {
return nil, err
}
key, err := encryption.KeyToBytes(secret, salt)
if err != nil {
return nil, err
}
block, err := aes.NewCipher(key)
if err != nil {
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.
ciphertext := make([]byte, encryption.SaltLength+aes.BlockSize+len(payload))
copy(ciphertext[:encryption.SaltLength], salt)
iv := ciphertext[encryption.SaltLength : encryption.SaltLength+aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return nil, err
}
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(ciphertext[encryption.SaltLength+aes.BlockSize:], payload)
return ciphertext, nil
}

View File

@@ -0,0 +1,20 @@
package provider
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_aesCfbCipher(t *testing.T) {
cipher := aesCfbCipher{}
ctx := context.Background()
encrypted, err := cipher.Encrypt(ctx, []byte("grafana"), "1234")
require.NoError(t, err)
assert.NotNil(t, encrypted)
assert.NotEmpty(t, encrypted)
}

View File

@@ -0,0 +1,67 @@
package provider
import (
"context"
"crypto/aes"
"crypto/cipher"
"errors"
"github.com/grafana/grafana/pkg/services/encryption"
)
type aesDecipher struct {
algorithm string
}
func (d aesDecipher) Decrypt(_ context.Context, payload []byte, secret string) ([]byte, error) {
if len(payload) < encryption.SaltLength {
return nil, errors.New("unable to compute salt")
}
salt := payload[:encryption.SaltLength]
key, err := encryption.KeyToBytes(secret, string(salt))
if err != nil {
return nil, err
}
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
switch d.algorithm {
case encryption.AesGcm:
return decryptGCM(block, payload)
default:
return decryptCFB(block, payload)
}
}
func decryptGCM(block cipher.Block, payload []byte) ([]byte, error) {
gcm, err := cipher.NewGCM(block)
if err != nil {
return nil, err
}
nonce := payload[encryption.SaltLength : encryption.SaltLength+gcm.NonceSize()]
ciphertext := payload[encryption.SaltLength+gcm.NonceSize():]
return gcm.Open(nil, nonce, ciphertext, nil)
}
func decryptCFB(block cipher.Block, payload []byte) ([]byte, error) {
// 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 {
return nil, errors.New("payload too short")
}
iv := payload[encryption.SaltLength : encryption.SaltLength+aes.BlockSize]
payload = payload[encryption.SaltLength+aes.BlockSize:]
payloadDst := make([]byte, len(payload))
stream := cipher.NewCFBDecrypter(block, iv)
// XORKeyStream can work in-place if the two arguments are the same.
stream.XORKeyStream(payloadDst, payload)
return payloadDst, nil
}

View File

@@ -0,0 +1,32 @@
package provider
import (
"context"
"testing"
"github.com/grafana/grafana/pkg/services/encryption"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_aesDecipher(t *testing.T) {
ctx := context.Background()
t.Run("aes-cfb", func(t *testing.T) {
cipher := aesDecipher{algorithm: encryption.AesCfb}
cfbEncryptedCiphertext := []byte{69, 84, 85, 120, 65, 82, 107, 88, 144, 188, 109, 229, 91, 88, 85, 113, 220, 35, 178, 190, 208, 182, 209, 91, 252, 119, 138, 133, 198, 8, 1}
decrypted, err := cipher.Decrypt(ctx, cfbEncryptedCiphertext, "1234")
require.NoError(t, err)
assert.Equal(t, []byte("grafana"), decrypted)
})
t.Run("aes-gcm", func(t *testing.T) {
cipher := aesDecipher{algorithm: encryption.AesGcm}
gcmEncryptedCiphertext := []byte{48, 99, 55, 50, 51, 48, 83, 66, 20, 99, 47, 238, 61, 44, 129, 125, 14, 37, 162, 230, 47, 31, 104, 70, 144, 223, 26, 51, 180, 17, 76, 52, 36, 93, 17, 203, 99, 158, 219, 102, 74, 173, 74}
decrypted, err := cipher.Decrypt(ctx, gcmEncryptedCiphertext, "1234")
require.NoError(t, err)
assert.Equal(t, []byte("grafana"), decrypted)
})
}

View File

@@ -0,0 +1,24 @@
package provider
import (
"github.com/grafana/grafana/pkg/services/encryption"
)
type Provider struct{}
func ProvideEncryptionProvider() Provider {
return Provider{}
}
func (p Provider) ProvideCiphers() map[string]encryption.Cipher {
return map[string]encryption.Cipher{
encryption.AesCfb: aesCfbCipher{},
}
}
func (p Provider) ProvideDeciphers() map[string]encryption.Decipher {
return map[string]encryption.Decipher{
encryption.AesCfb: aesDecipher{algorithm: encryption.AesCfb},
encryption.AesGcm: aesDecipher{algorithm: encryption.AesGcm},
}
}

View File

@@ -0,0 +1,23 @@
package service
import (
"testing"
"github.com/grafana/grafana/pkg/infra/usagestats"
encryptionprovider "github.com/grafana/grafana/pkg/services/encryption/provider"
"github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/require"
)
func SetupTestService(tb testing.TB) *Service {
tb.Helper()
usMock := &usagestats.UsageStatsMock{T: tb}
provider := encryptionprovider.ProvideEncryptionProvider()
settings := &setting.OSSImpl{Cfg: setting.NewCfg()}
service, err := ProvideEncryptionService(provider, usMock, settings)
require.NoError(tb, err)
return service
}

View File

@@ -0,0 +1,243 @@
package service
import (
"bytes"
"context"
"encoding/base64"
"errors"
"fmt"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/usagestats"
"github.com/grafana/grafana/pkg/services/encryption"
"github.com/grafana/grafana/pkg/setting"
)
const (
encryptionAlgorithmDelimiter = '*'
securitySection = "security.encryption"
encryptionAlgorithmKey = "algorithm"
defaultEncryptionAlgorithm = encryption.AesCfb
)
// Service must not be used for encryption.
// Use secrets.Service implementing envelope encryption instead.
type Service struct {
log log.Logger
settingsProvider setting.Provider
usageMetrics usagestats.Service
ciphers map[string]encryption.Cipher
deciphers map[string]encryption.Decipher
}
func ProvideEncryptionService(
provider encryption.Provider,
usageMetrics usagestats.Service,
settingsProvider setting.Provider,
) (*Service, error) {
s := &Service{
log: log.New("encryption"),
ciphers: provider.ProvideCiphers(),
deciphers: provider.ProvideDeciphers(),
usageMetrics: usageMetrics,
settingsProvider: settingsProvider,
}
algorithm := s.settingsProvider.
KeyValue(securitySection, encryptionAlgorithmKey).
MustString(defaultEncryptionAlgorithm)
if err := s.checkEncryptionAlgorithm(algorithm); err != nil {
return nil, err
}
settingsProvider.RegisterReloadHandler(securitySection, s)
s.registerUsageMetrics()
return s, nil
}
func (s *Service) checkEncryptionAlgorithm(algorithm string) error {
var err error
defer func() {
if err != nil {
s.log.Error("Wrong security encryption configuration", "algorithm", algorithm, "error", err)
}
}()
if _, ok := s.ciphers[algorithm]; !ok {
err = errors.New("no cipher registered for encryption algorithm configured")
return err
}
if _, ok := s.deciphers[algorithm]; !ok {
err = errors.New("no cipher registered for encryption algorithm configured")
return err
}
return nil
}
func (s *Service) registerUsageMetrics() {
s.usageMetrics.RegisterMetricsFunc(func(context.Context) (map[string]interface{}, error) {
algorithm := s.settingsProvider.
KeyValue(securitySection, encryptionAlgorithmKey).
MustString(defaultEncryptionAlgorithm)
return map[string]interface{}{
fmt.Sprintf("stats.encryption.%s.count", algorithm): 1,
}, nil
})
}
func (s *Service) Decrypt(ctx context.Context, payload []byte, secret string) ([]byte, error) {
var err error
defer func() {
if err != nil {
s.log.Error("Decryption failed", "error", err)
}
}()
var (
algorithm string
toDecrypt []byte
)
algorithm, toDecrypt, err = deriveEncryptionAlgorithm(payload)
if err != nil {
return nil, err
}
decipher, ok := s.deciphers[algorithm]
if !ok {
err = fmt.Errorf("no decipher available for algorithm '%s'", algorithm)
return nil, err
}
var decrypted []byte
decrypted, err = decipher.Decrypt(ctx, toDecrypt, secret)
return decrypted, err
}
func deriveEncryptionAlgorithm(payload []byte) (string, []byte, error) {
if len(payload) == 0 {
return "", nil, fmt.Errorf("unable to derive encryption algorithm")
}
if payload[0] != encryptionAlgorithmDelimiter {
return encryption.AesCfb, payload, nil // backwards compatibility
}
payload = payload[1:]
algorithmDelimiterIdx := bytes.Index(payload, []byte{encryptionAlgorithmDelimiter})
if algorithmDelimiterIdx == -1 {
return encryption.AesCfb, payload, nil // backwards compatibility
}
algorithmB64 := payload[:algorithmDelimiterIdx]
payload = payload[algorithmDelimiterIdx+1:]
algorithm := make([]byte, base64.RawStdEncoding.DecodedLen(len(algorithmB64)))
_, err := base64.RawStdEncoding.Decode(algorithm, algorithmB64)
if err != nil {
return "", nil, err
}
return string(algorithm), payload, nil
}
func (s *Service) Encrypt(ctx context.Context, payload []byte, secret string) ([]byte, error) {
var err error
defer func() {
if err != nil {
s.log.Error("Encryption failed", "error", err)
}
}()
algorithm := s.settingsProvider.
KeyValue(securitySection, encryptionAlgorithmKey).
MustString(defaultEncryptionAlgorithm)
cipher, ok := s.ciphers[algorithm]
if !ok {
err = fmt.Errorf("no cipher available for algorithm '%s'", algorithm)
return nil, err
}
var encrypted []byte
encrypted, err = cipher.Encrypt(ctx, payload, secret)
prefix := make([]byte, base64.RawStdEncoding.EncodedLen(len([]byte(algorithm)))+2)
base64.RawStdEncoding.Encode(prefix[1:], []byte(algorithm))
prefix[0] = encryptionAlgorithmDelimiter
prefix[len(prefix)-1] = encryptionAlgorithmDelimiter
ciphertext := make([]byte, len(prefix)+len(encrypted))
copy(ciphertext, prefix)
copy(ciphertext[len(prefix):], encrypted)
return ciphertext, nil
}
func (s *Service) EncryptJsonData(ctx context.Context, kv map[string]string, secret string) (map[string][]byte, error) {
encrypted := make(map[string][]byte)
for key, value := range kv {
encryptedData, err := s.Encrypt(ctx, []byte(value), secret)
if err != nil {
return nil, err
}
encrypted[key] = encryptedData
}
return encrypted, nil
}
func (s *Service) DecryptJsonData(ctx context.Context, sjd map[string][]byte, secret string) (map[string]string, error) {
decrypted := make(map[string]string)
for key, data := range sjd {
decryptedData, err := s.Decrypt(ctx, data, secret)
if err != nil {
return nil, err
}
decrypted[key] = string(decryptedData)
}
return decrypted, nil
}
func (s *Service) GetDecryptedValue(ctx context.Context, sjd map[string][]byte, key, fallback, secret string) string {
if value, ok := sjd[key]; ok {
decryptedData, err := s.Decrypt(ctx, value, secret)
if err != nil {
return fallback
}
return string(decryptedData)
}
return fallback
}
func (s *Service) Validate(section setting.Section) error {
s.log.Debug("Validating encryption config")
algorithm := section.KeyValue(encryptionAlgorithmKey).
MustString(defaultEncryptionAlgorithm)
if err := s.checkEncryptionAlgorithm(algorithm); err != nil {
return err
}
return nil
}
func (s *Service) Reload(_ setting.Section) error {
return nil
}

View File

@@ -0,0 +1,94 @@
package service
import (
"context"
"testing"
"github.com/grafana/grafana/pkg/infra/usagestats"
"github.com/grafana/grafana/pkg/services/encryption"
"github.com/grafana/grafana/pkg/services/encryption/provider"
"github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_Service(t *testing.T) {
ctx := context.Background()
encProvider := provider.Provider{}
usageStats := &usagestats.UsageStatsMock{}
settings := &setting.OSSImpl{Cfg: setting.NewCfg()}
svc, err := ProvideEncryptionService(encProvider, usageStats, settings)
require.NoError(t, err)
t.Run("decrypt empty payload should return error", func(t *testing.T) {
_, err := svc.Decrypt(context.Background(), []byte(""), "1234")
require.Error(t, err)
assert.Equal(t, "unable to derive encryption algorithm", err.Error())
})
t.Run("encrypt and decrypt with aes-cfb should work", func(t *testing.T) {
settings.Cfg.Raw.Section(securitySection).Key(encryptionAlgorithmKey).SetValue(encryption.AesCfb)
encrypted, err := svc.Encrypt(ctx, []byte("grafana"), "1234")
require.NoError(t, err)
decrypted, err := svc.Decrypt(ctx, encrypted, "1234")
require.NoError(t, err)
assert.Equal(t, []byte("grafana"), decrypted)
})
t.Run("decrypt with aes-gcm should work", func(t *testing.T) {
// Raw slice of bytes that corresponds to the following ciphertext:
// - 'grafana' as payload
// - '1234' as secret
// - 'aes-gcm' as encryption algorithm
ciphertext := []byte{42, 89, 87, 86, 122, 76, 87, 100, 106, 98, 81, 42, 48, 99, 55, 50, 51, 48, 83, 66, 20, 99, 47, 238, 61, 44, 129, 125, 14, 37, 162, 230, 47, 31, 104, 70, 144, 223, 26, 51, 180, 17, 76, 52, 36, 93, 17, 203, 99, 158, 219, 102, 74, 173, 74}
decrypted, err := svc.Decrypt(context.Background(), ciphertext, "1234")
require.NoError(t, err)
assert.Equal(t, []byte("grafana"), decrypted)
})
t.Run("encrypt with aes-gcm should fail", func(t *testing.T) {
settings.Cfg.Raw.Section(securitySection).Key(encryptionAlgorithmKey).SetValue(encryption.AesGcm)
_, err := svc.Encrypt(ctx, []byte("grafana"), "1234")
require.Error(t, err)
})
t.Run("decrypting legacy ciphertext should work", func(t *testing.T) {
// Raw slice of bytes that corresponds to the following ciphertext:
// - 'grafana' as payload
// - '1234' as secret
// - no encryption algorithm metadata
ciphertext := []byte{73, 71, 50, 57, 121, 110, 90, 109, 115, 23, 237, 13, 130, 188, 151, 118, 98, 103, 80, 209, 79, 143, 22, 122, 44, 40, 102, 41, 136, 16, 27}
decrypted, err := svc.Decrypt(context.Background(), ciphertext, "1234")
require.NoError(t, err)
assert.Equal(t, []byte("grafana"), decrypted)
})
}
func Test_Service_MissingProvider(t *testing.T) {
encProvider := fakeProvider{}
usageStats := &usagestats.UsageStatsMock{}
settings := &setting.OSSImpl{Cfg: setting.NewCfg()}
service, err := ProvideEncryptionService(encProvider, usageStats, settings)
assert.Nil(t, service)
assert.Error(t, err)
}
type fakeProvider struct{}
func (p fakeProvider) ProvideCiphers() map[string]encryption.Cipher {
return nil
}
func (p fakeProvider) ProvideDeciphers() map[string]encryption.Decipher {
return nil
}

View File

@@ -10,7 +10,7 @@ import (
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting" "github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/alerting/notifiers" "github.com/grafana/grafana/pkg/services/alerting/notifiers"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@@ -33,6 +33,8 @@ func TestNotificationAsConfig(t *testing.T) {
var sqlStore *sqlstore.SQLStore var sqlStore *sqlstore.SQLStore
logger := log.New("fake.log") logger := log.New("fake.log")
encryptionService := encryptionservice.SetupTestService(t)
t.Run("Testing notification as configuration", func(t *testing.T) { t.Run("Testing notification as configuration", func(t *testing.T) {
setup := func() { setup := func() {
sqlStore = sqlstore.InitTestDB(t) sqlStore = sqlstore.InitTestDB(t)
@@ -61,7 +63,7 @@ func TestNotificationAsConfig(t *testing.T) {
_ = os.Setenv("TEST_VAR", "default") _ = os.Setenv("TEST_VAR", "default")
cfgProvider := &configReader{ cfgProvider := &configReader{
orgStore: sqlStore, orgStore: sqlStore,
encryptionService: ossencryption.ProvideService(), encryptionService: encryptionService,
log: log.New("test logger"), log: log.New("test logger"),
} }
@@ -140,7 +142,7 @@ func TestNotificationAsConfig(t *testing.T) {
setup() setup()
fakeAlertNotification := &fakeAlertNotification{} fakeAlertNotification := &fakeAlertNotification{}
fakeAlertNotification.ExpectedAlertNotification = &models.AlertNotification{OrgId: 1} fakeAlertNotification.ExpectedAlertNotification = &models.AlertNotification{OrgId: 1}
dc := newNotificationProvisioner(sqlStore, fakeAlertNotification, ossencryption.ProvideService(), nil, logger) dc := newNotificationProvisioner(sqlStore, fakeAlertNotification, encryptionService, nil, logger)
err := dc.applyChanges(context.Background(), twoNotificationsConfig) err := dc.applyChanges(context.Background(), twoNotificationsConfig)
if err != nil { if err != nil {
@@ -166,7 +168,7 @@ func TestNotificationAsConfig(t *testing.T) {
require.Equal(t, len(notificationsQuery.Result), 1) require.Equal(t, len(notificationsQuery.Result), 1)
t.Run("should update one notification", func(t *testing.T) { t.Run("should update one notification", func(t *testing.T) {
dc := newNotificationProvisioner(sqlStore, &fakeAlertNotification{}, ossencryption.ProvideService(), nil, logger) dc := newNotificationProvisioner(sqlStore, &fakeAlertNotification{}, encryptionService, nil, logger)
err = dc.applyChanges(context.Background(), twoNotificationsConfig) err = dc.applyChanges(context.Background(), twoNotificationsConfig)
if err != nil { if err != nil {
t.Fatalf("applyChanges return an error %v", err) t.Fatalf("applyChanges return an error %v", err)
@@ -175,7 +177,7 @@ func TestNotificationAsConfig(t *testing.T) {
}) })
t.Run("Two notifications with is_default", func(t *testing.T) { t.Run("Two notifications with is_default", func(t *testing.T) {
setup() setup()
dc := newNotificationProvisioner(sqlStore, &fakeAlertNotification{}, ossencryption.ProvideService(), nil, logger) dc := newNotificationProvisioner(sqlStore, &fakeAlertNotification{}, encryptionService, nil, logger)
err := dc.applyChanges(context.Background(), doubleNotificationsConfig) err := dc.applyChanges(context.Background(), doubleNotificationsConfig)
t.Run("should both be inserted", func(t *testing.T) { t.Run("should both be inserted", func(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
@@ -210,7 +212,7 @@ func TestNotificationAsConfig(t *testing.T) {
require.Equal(t, len(notificationsQuery.Result), 2) require.Equal(t, len(notificationsQuery.Result), 2)
t.Run("should have two new notifications", func(t *testing.T) { t.Run("should have two new notifications", func(t *testing.T) {
dc := newNotificationProvisioner(sqlStore, &fakeAlertNotification{}, ossencryption.ProvideService(), nil, logger) dc := newNotificationProvisioner(sqlStore, &fakeAlertNotification{}, encryptionService, nil, logger)
err := dc.applyChanges(context.Background(), twoNotificationsConfig) err := dc.applyChanges(context.Background(), twoNotificationsConfig)
if err != nil { if err != nil {
t.Fatalf("applyChanges return an error %v", err) t.Fatalf("applyChanges return an error %v", err)
@@ -239,7 +241,7 @@ func TestNotificationAsConfig(t *testing.T) {
err = sqlStore.CreateAlertNotificationCommand(context.Background(), &existingNotificationCmd) err = sqlStore.CreateAlertNotificationCommand(context.Background(), &existingNotificationCmd)
require.NoError(t, err) require.NoError(t, err)
dc := newNotificationProvisioner(sqlStore, &fakeAlertNotification{}, ossencryption.ProvideService(), nil, logger) dc := newNotificationProvisioner(sqlStore, &fakeAlertNotification{}, encryptionService, nil, logger)
err = dc.applyChanges(context.Background(), correctPropertiesWithOrgName) err = dc.applyChanges(context.Background(), correctPropertiesWithOrgName)
if err != nil { if err != nil {
t.Fatalf("applyChanges return an error %v", err) t.Fatalf("applyChanges return an error %v", err)
@@ -248,7 +250,7 @@ func TestNotificationAsConfig(t *testing.T) {
t.Run("Config doesn't contain required field", func(t *testing.T) { t.Run("Config doesn't contain required field", func(t *testing.T) {
setup() setup()
dc := newNotificationProvisioner(sqlStore, &fakeAlertNotification{}, ossencryption.ProvideService(), nil, logger) dc := newNotificationProvisioner(sqlStore, &fakeAlertNotification{}, encryptionService, nil, logger)
err := dc.applyChanges(context.Background(), noRequiredFields) err := dc.applyChanges(context.Background(), noRequiredFields)
require.NotNil(t, err) require.NotNil(t, err)
@@ -262,7 +264,7 @@ func TestNotificationAsConfig(t *testing.T) {
t.Run("Empty yaml file", func(t *testing.T) { t.Run("Empty yaml file", func(t *testing.T) {
t.Run("should have not changed repo", func(t *testing.T) { t.Run("should have not changed repo", func(t *testing.T) {
setup() setup()
dc := newNotificationProvisioner(sqlStore, &fakeAlertNotification{}, ossencryption.ProvideService(), nil, logger) dc := newNotificationProvisioner(sqlStore, &fakeAlertNotification{}, encryptionService, nil, logger)
err := dc.applyChanges(context.Background(), emptyFile) err := dc.applyChanges(context.Background(), emptyFile)
if err != nil { if err != nil {
t.Fatalf("applyChanges return an error %v", err) t.Fatalf("applyChanges return an error %v", err)
@@ -277,7 +279,7 @@ func TestNotificationAsConfig(t *testing.T) {
t.Run("Broken yaml should return error", func(t *testing.T) { t.Run("Broken yaml should return error", func(t *testing.T) {
reader := &configReader{ reader := &configReader{
orgStore: sqlStore, orgStore: sqlStore,
encryptionService: ossencryption.ProvideService(), encryptionService: encryptionService,
log: log.New("test logger"), log: log.New("test logger"),
} }
@@ -288,7 +290,7 @@ func TestNotificationAsConfig(t *testing.T) {
t.Run("Skip invalid directory", func(t *testing.T) { t.Run("Skip invalid directory", func(t *testing.T) {
cfgProvider := &configReader{ cfgProvider := &configReader{
orgStore: sqlStore, orgStore: sqlStore,
encryptionService: ossencryption.ProvideService(), encryptionService: encryptionService,
log: log.New("test logger"), log: log.New("test logger"),
} }
@@ -302,7 +304,7 @@ func TestNotificationAsConfig(t *testing.T) {
t.Run("Unknown notifier should return error", func(t *testing.T) { t.Run("Unknown notifier should return error", func(t *testing.T) {
cfgProvider := &configReader{ cfgProvider := &configReader{
orgStore: sqlStore, orgStore: sqlStore,
encryptionService: ossencryption.ProvideService(), encryptionService: encryptionService,
log: log.New("test logger"), log: log.New("test logger"),
} }
_, err := cfgProvider.readConfig(context.Background(), unknownNotifier) _, err := cfgProvider.readConfig(context.Background(), unknownNotifier)
@@ -313,7 +315,7 @@ func TestNotificationAsConfig(t *testing.T) {
t.Run("Read incorrect properties", func(t *testing.T) { t.Run("Read incorrect properties", func(t *testing.T) {
cfgProvider := &configReader{ cfgProvider := &configReader{
orgStore: sqlStore, orgStore: sqlStore,
encryptionService: ossencryption.ProvideService(), encryptionService: encryptionService,
log: log.New("test logger"), log: log.New("test logger"),
} }
_, err := cfgProvider.readConfig(context.Background(), incorrectSettings) _, err := cfgProvider.readConfig(context.Background(), incorrectSettings)

View File

@@ -4,7 +4,8 @@ import (
"testing" "testing"
"github.com/grafana/grafana/pkg/infra/usagestats" "github.com/grafana/grafana/pkg/infra/usagestats"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionprovider "github.com/grafana/grafana/pkg/services/encryption/provider"
encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/kmsproviders/osskmsproviders" "github.com/grafana/grafana/pkg/services/kmsproviders/osskmsproviders"
"github.com/grafana/grafana/pkg/services/secrets" "github.com/grafana/grafana/pkg/services/secrets"
@@ -37,10 +38,14 @@ func setupTestService(tb testing.TB, store secrets.Store, features *featuremgmt.
require.NoError(tb, err) require.NoError(tb, err)
cfg := &setting.Cfg{Raw: raw} cfg := &setting.Cfg{Raw: raw}
settings := &setting.OSSImpl{Cfg: cfg} settings := &setting.OSSImpl{Cfg: cfg}
encryption := ossencryption.ProvideService() encProvider := encryptionprovider.Provider{}
usageStats := &usagestats.UsageStatsMock{}
encryption, err := encryptionservice.ProvideEncryptionService(encProvider, usageStats, settings)
require.NoError(tb, err)
secretsService, err := ProvideSecretsService( secretsService, err := ProvideSecretsService(
store, store,
osskmsproviders.ProvideService(encryption, settings, features), osskmsproviders.ProvideService(encryption, settings, features),

View File

@@ -6,7 +6,8 @@ import (
"time" "time"
"github.com/grafana/grafana/pkg/infra/usagestats" "github.com/grafana/grafana/pkg/infra/usagestats"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption" encryptionprovider "github.com/grafana/grafana/pkg/services/encryption/provider"
encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/kmsproviders/osskmsproviders" "github.com/grafana/grafana/pkg/services/kmsproviders/osskmsproviders"
"github.com/grafana/grafana/pkg/services/secrets" "github.com/grafana/grafana/pkg/services/secrets"
@@ -175,8 +176,14 @@ func TestSecretsService_UseCurrentProvider(t *testing.T) {
raw, err := ini.Load([]byte(rawCfg)) raw, err := ini.Load([]byte(rawCfg))
require.NoError(t, err) require.NoError(t, err)
encryptionService := ossencryption.ProvideService()
settings := &setting.OSSImpl{Cfg: &setting.Cfg{Raw: raw}} settings := &setting.OSSImpl{Cfg: &setting.Cfg{Raw: raw}}
encProvider := encryptionprovider.Provider{}
usageStats := &usagestats.UsageStatsMock{}
encryptionService, err := encryptionservice.ProvideEncryptionService(encProvider, usageStats, settings)
require.NoError(t, err)
features := featuremgmt.WithFeatures() features := featuremgmt.WithFeatures()
kms := newFakeKMS(osskmsproviders.ProvideService(encryptionService, settings, features)) kms := newFakeKMS(osskmsproviders.ProvideService(encryptionService, settings, features))
secretStore := database.ProvideSecretsStore(sqlstore.InitTestDB(t)) secretStore := database.ProvideSecretsStore(sqlstore.InitTestDB(t))