diff --git a/pkg/registry/apps/alerting/notifications/receiver/legacy_storage.go b/pkg/registry/apps/alerting/notifications/receiver/legacy_storage.go index 84c0fe9f7fd..f8f663a8853 100644 --- a/pkg/registry/apps/alerting/notifications/receiver/legacy_storage.go +++ b/pkg/registry/apps/alerting/notifications/receiver/legacy_storage.go @@ -17,7 +17,6 @@ import ( "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request" alertingac "github.com/grafana/grafana/pkg/services/ngalert/accesscontrol" ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" - "github.com/grafana/grafana/pkg/services/ngalert/notifier/legacy_storage" ) var ( @@ -25,7 +24,7 @@ var ( ) type ReceiverService interface { - GetReceiver(ctx context.Context, q ngmodels.GetReceiverQuery, user identity.Requester) (*ngmodels.Receiver, error) + GetReceiver(ctx context.Context, uid string, decrypt bool, user identity.Requester) (*ngmodels.Receiver, error) GetReceivers(ctx context.Context, q ngmodels.GetReceiversQuery, user identity.Requester) ([]*ngmodels.Receiver, error) CreateReceiver(ctx context.Context, r *ngmodels.Receiver, orgID int64, user identity.Requester) (*ngmodels.Receiver, error) UpdateReceiver(ctx context.Context, r *ngmodels.Receiver, storedSecureFields map[string][]string, orgID int64, user identity.Requester) (*ngmodels.Receiver, error) @@ -116,22 +115,12 @@ func (s *legacyStorage) Get(ctx context.Context, uid string, _ *metav1.GetOption return nil, err } - name, err := legacy_storage.UidToName(uid) - if err != nil { - return nil, apierrors.NewNotFound(ResourceInfo.GroupResource(), uid) - } - q := ngmodels.GetReceiverQuery{ - OrgID: info.OrgID, - Name: name, - Decrypt: false, - } - user, err := identity.GetRequester(ctx) if err != nil { return nil, err } - r, err := s.service.GetReceiver(ctx, q, user) + r, err := s.service.GetReceiver(ctx, uid, false, user) if err != nil { return nil, err } diff --git a/pkg/services/ngalert/models/receivers.go b/pkg/services/ngalert/models/receivers.go index 1601ddc94e5..106203e4e33 100644 --- a/pkg/services/ngalert/models/receivers.go +++ b/pkg/services/ngalert/models/receivers.go @@ -16,13 +16,6 @@ import ( "github.com/grafana/alerting/receivers/schema" ) -// GetReceiverQuery represents a query for a single receiver. -type GetReceiverQuery struct { - OrgID int64 - Name string - Decrypt bool -} - // GetReceiversQuery represents a query for receiver groups. type GetReceiversQuery struct { OrgID int64 diff --git a/pkg/services/ngalert/notifier/crypto.go b/pkg/services/ngalert/notifier/crypto.go index 246cd03d64d..04a651a174f 100644 --- a/pkg/services/ngalert/notifier/crypto.go +++ b/pkg/services/ngalert/notifier/crypto.go @@ -378,3 +378,29 @@ func EncryptedReceivers(receivers []*definitions.PostableApiReceiver, encryptFn } return encrypted, nil } + +// DecryptIntegrationSettings returns a function to decrypt integration settings. +func DecryptIntegrationSettings(ctx context.Context, ss secretService) models.DecryptFn { + return func(value string) (string, error) { + decoded, err := base64.StdEncoding.DecodeString(value) + if err != nil { + return "", err + } + decrypted, err := ss.Decrypt(ctx, decoded) + if err != nil { + return "", err + } + return string(decrypted), nil + } +} + +// EncryptIntegrationSettings returns a function to encrypt integration settings. +func EncryptIntegrationSettings(ctx context.Context, ss secretService) models.EncryptFn { + return func(payload string) (string, error) { + encrypted, err := ss.Encrypt(ctx, []byte(payload), secrets.WithoutScope()) + if err != nil { + return "", err + } + return base64.StdEncoding.EncodeToString(encrypted), nil + } +} diff --git a/pkg/services/ngalert/notifier/errors.go b/pkg/services/ngalert/notifier/errors.go index 337dfa7cb3b..08f4c967049 100644 --- a/pkg/services/ngalert/notifier/errors.go +++ b/pkg/services/ngalert/notifier/errors.go @@ -1,9 +1,37 @@ package notifier -import "github.com/grafana/grafana/pkg/apimachinery/errutil" +import ( + "errors" + "slices" + + "github.com/grafana/alerting/receivers/schema" + + "github.com/grafana/grafana/pkg/apimachinery/errutil" +) // WithPublicError sets the public message of an errutil error to the error message. func WithPublicError(err errutil.Error) error { err.PublicMessage = err.Error() return err } + +// If provided error is errutil.Error it appends fields that caused the error to public payload +func makeProtectedFieldsAuthzError(err error, diff map[string][]schema.IntegrationFieldPath) error { + var authzErr errutil.Error + if !errors.As(err, &authzErr) { + return err + } + if authzErr.PublicPayload == nil { + authzErr.PublicPayload = map[string]interface{}{} + } + fields := make(map[string][]string, len(diff)) + for field, paths := range diff { + fields[field] = make([]string, len(paths)) + for i, path := range paths { + fields[field][i] = path.String() + } + slices.Sort(fields[field]) + } + authzErr.PublicPayload["changed_protected_fields"] = fields + return authzErr +} diff --git a/pkg/services/ngalert/notifier/receiver_svc.go b/pkg/services/ngalert/notifier/receiver_svc.go index e05b12a2920..dc3e9d4b8eb 100644 --- a/pkg/services/ngalert/notifier/receiver_svc.go +++ b/pkg/services/ngalert/notifier/receiver_svc.go @@ -2,7 +2,6 @@ package notifier import ( "context" - "encoding/base64" "errors" "fmt" "strings" @@ -133,30 +132,33 @@ func (rs *ReceiverService) loadProvenances(ctx context.Context, orgID int64) (ma return rs.provisioningStore.GetProvenances(ctx, orgID, (&models.Integration{}).ResourceType()) } -// GetReceiver returns a receiver by name. +// GetReceiver returns a receiver by its UID. // The receiver's secure settings are decrypted if requested and the user has access to do so. -func (rs *ReceiverService) GetReceiver(ctx context.Context, q models.GetReceiverQuery, user identity.Requester) (*models.Receiver, error) { +func (rs *ReceiverService) GetReceiver(ctx context.Context, uid string, decrypt bool, user identity.Requester) (*models.Receiver, error) { + if user == nil { + return nil, errors.New("user is required") + } ctx, span := rs.tracer.Start(ctx, "alerting.receivers.get", trace.WithAttributes( - attribute.Int64("query_org_id", q.OrgID), - attribute.String("query_name", q.Name), - attribute.Bool("query_decrypt", q.Decrypt), + attribute.Int64("query_org_id", user.GetOrgID()), + attribute.String("query_uid", uid), + attribute.Bool("query_decrypt", decrypt), )) defer span.End() - revision, err := rs.cfgStore.Get(ctx, q.OrgID) + revision, err := rs.cfgStore.Get(ctx, user.GetOrgID()) if err != nil { return nil, err } - prov, err := rs.loadProvenances(ctx, q.OrgID) + prov, err := rs.loadProvenances(ctx, user.GetOrgID()) if err != nil { return nil, err } - rcv, err := revision.GetReceiver(legacy_storage.NameToUid(q.Name), prov) + rcv, err := revision.GetReceiver(uid, prov) if err != nil { if errors.Is(err, legacy_storage.ErrReceiverNotFound) && rs.includeImported { - imported := rs.getImportedReceivers(ctx, span, []string{legacy_storage.NameToUid(q.Name)}, revision) + imported := rs.getImportedReceivers(ctx, span, []string{uid}, revision) if len(imported) > 0 { rcv = imported[0] } @@ -171,14 +173,14 @@ func (rs *ReceiverService) GetReceiver(ctx context.Context, q models.GetReceiver )) auth := rs.authz.AuthorizeReadDecrypted - if !q.Decrypt { + if !decrypt { auth = rs.authz.AuthorizeRead } if err := auth(ctx, user, rcv); err != nil { return nil, err } - if q.Decrypt { + if decrypt { err := rcv.Decrypt(rs.decryptor(ctx)) if err != nil { rs.log.FromContext(ctx).Warn("Failed to decrypt secure settings", "name", rcv.Name, "error", err) @@ -684,28 +686,12 @@ func (rs *ReceiverService) deleteProvenances(ctx context.Context, orgID int64, i // decryptor returns a models.DecryptFn that decrypts a secure setting. If decryption fails, the fallback value is used. func (rs *ReceiverService) decryptor(ctx context.Context) models.DecryptFn { - return func(value string) (string, error) { - decoded, err := base64.StdEncoding.DecodeString(value) - if err != nil { - return "", err - } - decrypted, err := rs.encryptionService.Decrypt(ctx, decoded) - if err != nil { - return "", err - } - return string(decrypted), nil - } + return DecryptIntegrationSettings(ctx, rs.encryptionService) } // encryptor creates an encrypt function that delegates to secrets.Service and returns the base64 encoded result. func (rs *ReceiverService) encryptor(ctx context.Context) models.EncryptFn { - return func(payload string) (string, error) { - s, err := rs.encryptionService.Encrypt(ctx, []byte(payload), secrets.WithoutScope()) - if err != nil { - return "", err - } - return base64.StdEncoding.EncodeToString(s), nil - } + return EncryptIntegrationSettings(ctx, rs.encryptionService) } // checkOptimisticConcurrency checks if the existing receiver's version matches the desired version. diff --git a/pkg/services/ngalert/notifier/receiver_svc_err.go b/pkg/services/ngalert/notifier/receiver_svc_err.go deleted file mode 100644 index 06b27602f75..00000000000 --- a/pkg/services/ngalert/notifier/receiver_svc_err.go +++ /dev/null @@ -1,30 +0,0 @@ -package notifier - -import ( - "errors" - "slices" - - "github.com/grafana/alerting/receivers/schema" - - "github.com/grafana/grafana/pkg/apimachinery/errutil" -) - -func makeProtectedFieldsAuthzError(err error, diff map[string][]schema.IntegrationFieldPath) error { - var authzErr errutil.Error - if !errors.As(err, &authzErr) { - return err - } - if authzErr.PublicPayload == nil { - authzErr.PublicPayload = map[string]interface{}{} - } - fields := make(map[string][]string, len(diff)) - for field, paths := range diff { - fields[field] = make([]string, len(paths)) - for i, path := range paths { - fields[field][i] = path.String() - } - slices.Sort(fields[field]) - } - authzErr.PublicPayload["changed_protected_fields"] = fields - return authzErr -} diff --git a/pkg/services/ngalert/notifier/receiver_svc_test.go b/pkg/services/ngalert/notifier/receiver_svc_test.go index 10e84f33b62..08c66411f16 100644 --- a/pkg/services/ngalert/notifier/receiver_svc_test.go +++ b/pkg/services/ngalert/notifier/receiver_svc_test.go @@ -50,7 +50,7 @@ func TestIntegrationReceiverService_GetReceiver(t *testing.T) { t.Run("service gets receiver from AM config", func(t *testing.T) { sut := createReceiverServiceSut(t, secretsService) - recv, err := sut.GetReceiver(context.Background(), singleQ(1, "slack receiver"), redactedUser) + recv, err := sut.GetReceiver(context.Background(), legacy_storage.NameToUid("slack receiver"), false, redactedUser) require.NoError(t, err) require.Equal(t, "slack receiver", recv.Name) require.Len(t, recv.Integrations, 1) @@ -60,7 +60,7 @@ func TestIntegrationReceiverService_GetReceiver(t *testing.T) { t.Run("service returns error when receiver does not exist", func(t *testing.T) { sut := createReceiverServiceSut(t, secretsService) - _, err := sut.GetReceiver(context.Background(), singleQ(1, "receiver1"), redactedUser) + _, err := sut.GetReceiver(context.Background(), legacy_storage.NameToUid("receiver1"), false, redactedUser) require.ErrorIs(t, err, legacy_storage.ErrReceiverNotFound) }) @@ -68,7 +68,7 @@ func TestIntegrationReceiverService_GetReceiver(t *testing.T) { t.Run("gets imported receivers", func(t *testing.T) { sut := createReceiverServiceSut(t, secretsService, withImportedIncluded) - recv, err := sut.GetReceiver(context.Background(), singleQ(1, "receiver1"), redactedUser) + recv, err := sut.GetReceiver(context.Background(), legacy_storage.NameToUid("receiver1"), false, redactedUser) require.NoError(t, err) assert.Equal(t, models.ResourceOriginImported, recv.Origin) assert.Equal(t, "receiver1", recv.Name) @@ -81,9 +81,9 @@ func TestIntegrationReceiverService_GetReceiver(t *testing.T) { t.Run("falls to only Grafana if cannot read imported receivers", func(t *testing.T) { sut := createReceiverServiceSut(t, secretsService, withImportedIncluded, withInvalidExtraConfig) - _, err := sut.GetReceiver(context.Background(), singleQ(1, "receiver1"), redactedUser) + _, err := sut.GetReceiver(context.Background(), legacy_storage.NameToUid("receiver1"), false, redactedUser) require.ErrorIs(t, err, legacy_storage.ErrReceiverNotFound) - _, err = sut.GetReceiver(context.Background(), singleQ(1, "slack receiver"), redactedUser) + _, err = sut.GetReceiver(context.Background(), legacy_storage.NameToUid("slack receiver"), false, redactedUser) require.NoError(t, err) }) }) @@ -187,12 +187,6 @@ func TestIntegrationReceiverService_DecryptRedact(t *testing.T) { user: readUser, err: "[alerting.unauthorized] user is not authorized to read any decrypted receiver", }, - { - name: "service returns error if user is nil and decrypt is true", - decrypt: true, - user: nil, - err: "[alerting.unauthorized] user is not authorized to read any decrypted receiver", - }, { name: "service decrypts receivers with permission", decrypt: true, @@ -224,18 +218,16 @@ func TestIntegrationReceiverService_DecryptRedact(t *testing.T) { }, } - for _, o := range origin { - for _, method := range getMethods { - t.Run(fmt.Sprintf("%s %s", tc.name, method), func(t *testing.T) { + for _, method := range getMethods { + t.Run(fmt.Sprintf("%s %s", tc.name, method), func(t *testing.T) { + for _, o := range origin { t.Run(fmt.Sprintf("%s %s (%s)", tc.name, method, o.origin), func(t *testing.T) { sut := createReceiverServiceSut(t, secretsService, o.opts...) var res *models.Receiver var err error if method == "single" { - q := singleQ(1, o.receiver) - q.Decrypt = tc.decrypt - res, err = sut.GetReceiver(context.Background(), q, tc.user) + res, err = sut.GetReceiver(context.Background(), legacy_storage.NameToUid(o.receiver), tc.decrypt, tc.user) } else { q := multiQ(1, o.receiver) q.Decrypt = tc.decrypt @@ -267,8 +259,8 @@ func TestIntegrationReceiverService_DecryptRedact(t *testing.T) { require.NotEqual(t, o.decryptedSettingValue, res.Integrations[0].SecureSettings[o.secureSettingKey]) } }) - }) - } + } + }) } } } @@ -412,8 +404,7 @@ func TestReceiverService_Delete(t *testing.T) { // Ensure receiver saved to store is correct. name, err := legacy_storage.UidToName(tc.deleteUID) require.NoError(t, err) - q := models.GetReceiverQuery{OrgID: tc.user.GetOrgID(), Name: name} - _, err = sut.GetReceiver(context.Background(), q, writer) + _, err = sut.GetReceiver(context.Background(), legacy_storage.NameToUid(name), false, writer) assert.ErrorIs(t, err, legacy_storage.ErrReceiverNotFound) provenances, err := sut.provisioningStore.GetProvenances(context.Background(), tc.user.GetOrgID(), (&definitions.EmbeddedContactPoint{}).ResourceType()) @@ -626,8 +617,7 @@ func TestReceiverService_Create(t *testing.T) { assert.Equal(t, tc.expectedCreate, *created) // Ensure receiver saved to store is correct. - q := models.GetReceiverQuery{OrgID: tc.user.GetOrgID(), Name: tc.receiver.Name, Decrypt: true} - stored, err := sut.GetReceiver(context.Background(), q, decryptUser) + stored, err := sut.GetReceiver(context.Background(), legacy_storage.NameToUid(tc.receiver.Name), true, decryptUser) require.NoError(t, err) decrypted := models.CopyReceiverWith(tc.expectedCreate, models.ReceiverMuts.Decrypted(models.Base64Decrypt)) decrypted.Version = tc.expectedCreate.Version // Version is calculated before decryption. @@ -931,8 +921,7 @@ func TestReceiverService_Update(t *testing.T) { assert.Equal(t, tc.expectedUpdate, *updated) // Ensure receiver saved to store is correct. - q := models.GetReceiverQuery{OrgID: tc.user.GetOrgID(), Name: tc.receiver.Name, Decrypt: true} - stored, err := sut.GetReceiver(context.Background(), q, decryptUser) + stored, err := sut.GetReceiver(context.Background(), legacy_storage.NameToUid(tc.receiver.Name), true, decryptUser) require.NoError(t, err) decrypted := models.CopyReceiverWith(tc.expectedUpdate, models.ReceiverMuts.Decrypted(models.Base64Decrypt)) decrypted.Version = tc.expectedUpdate.Version // Version is calculated before decryption. @@ -1054,7 +1043,7 @@ func TestReceiverService_UpdateReceiverName(t *testing.T) { sut.ruleNotificationsStore = ruleStore newReceiverName = "receiver1" - actual, err := sut.GetReceiver(context.Background(), models.GetReceiverQuery{OrgID: writer.GetOrgID(), Name: newReceiverName}, writer) + actual, err := sut.GetReceiver(context.Background(), legacy_storage.NameToUid(newReceiverName), false, writer) require.NoError(t, err) require.Equal(t, models.ResourceOriginImported, actual.Origin) require.Equal(t, newReceiverName, actual.Name) @@ -1067,7 +1056,7 @@ func TestReceiverService_UpdateReceiverName(t *testing.T) { require.NotEqual(t, actual, recv) require.Equal(t, models.ResourceOriginGrafana, recv.Origin) - actual, err = sut.GetReceiver(context.Background(), models.GetReceiverQuery{OrgID: writer.GetOrgID(), Name: newReceiverName}, writer) + actual, err = sut.GetReceiver(context.Background(), legacy_storage.NameToUid(newReceiverName), false, writer) require.NoError(t, err) require.Equal(t, recv.Name, actual.Name) }) @@ -1185,7 +1174,7 @@ func TestReceiverServiceAC_Read(t *testing.T) { return false } for _, recv := range allReceivers() { - response, err := sut.GetReceiver(context.Background(), singleQ(orgId, recv.Name), usr) + response, err := sut.GetReceiver(context.Background(), legacy_storage.NameToUid(recv.Name), false, usr) if isVisible(recv.UID) { require.NoErrorf(t, err, "receiver '%s' should be visible, but isn't", recv.Name) assert.NotNil(t, response) @@ -1207,7 +1196,7 @@ func TestReceiverServiceAC_Read(t *testing.T) { } sut.authz = ac.NewReceiverAccess[*models.Receiver](acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), true) for _, recv := range allReceivers() { - response, err := sut.GetReceiver(context.Background(), singleQ(orgId, recv.Name), usr) + response, err := sut.GetReceiver(context.Background(), legacy_storage.NameToUid(recv.Name), false, usr) if isVisibleInProvisioning(recv.UID) { require.NoErrorf(t, err, "receiver '%s' should be visible, but isn't", recv.Name) assert.NotNil(t, response) @@ -1766,7 +1755,7 @@ func TestReceiverService_AccessControlMetadata(t *testing.T) { }, }} - r, err := sut.GetReceiver(context.Background(), models.GetReceiverQuery{OrgID: 1, Name: "receiver1"}, admin) + r, err := sut.GetReceiver(context.Background(), legacy_storage.NameToUid("receiver1"), false, admin) require.NoError(t, err) t.Run("should override metadata for imported receivers", func(t *testing.T) { @@ -1842,13 +1831,6 @@ func createEncryptedConfig(t *testing.T, secretService secretService, extraConfi return string(bytes) } -func singleQ(orgID int64, name string) models.GetReceiverQuery { - return models.GetReceiverQuery{ - OrgID: orgID, - Name: name, - } -} - func multiQ(orgID int64, names ...string) models.GetReceiversQuery { return models.GetReceiversQuery{ OrgID: orgID, diff --git a/pkg/services/ngalert/remote/alertmanager.go b/pkg/services/ngalert/remote/alertmanager.go index a7c99f8518c..60740d935af 100644 --- a/pkg/services/ngalert/remote/alertmanager.go +++ b/pkg/services/ngalert/remote/alertmanager.go @@ -40,6 +40,7 @@ import ( "github.com/grafana/grafana/pkg/services/ngalert/notifier" remoteClient "github.com/grafana/grafana/pkg/services/ngalert/remote/client" "github.com/grafana/grafana/pkg/services/ngalert/sender" + "github.com/grafana/grafana/pkg/services/secrets" "github.com/grafana/grafana/pkg/util/cmputil" ) @@ -57,6 +58,7 @@ func NoopAutogenFn(_ context.Context, _ log.Logger, _ int64, _ *apimodels.Postab } type Crypto interface { + Encrypt(ctx context.Context, payload []byte, opt secrets.EncryptionOptions) ([]byte, error) Decrypt(ctx context.Context, payload []byte) ([]byte, error) DecryptExtraConfigs(ctx context.Context, config *apimodels.PostableUserConfig) error } @@ -289,20 +291,6 @@ func (am *Alertmanager) isDefaultConfiguration(configHash string) bool { return configHash == am.defaultConfigHash } -func decrypter(ctx context.Context, crypto Crypto) models.DecryptFn { - return func(value string) (string, error) { - decoded, err := base64.StdEncoding.DecodeString(value) - if err != nil { - return "", err - } - decrypted, err := crypto.Decrypt(ctx, decoded) - if err != nil { - return "", err - } - return string(decrypted), nil - } -} - // buildConfiguration takes a raw Alertmanager configuration and returns a config that the remote Alertmanager can use. // It parses the initial configuration, adds auto-generated routes, decrypts receivers, and merges the extra configs. func (am *Alertmanager) buildConfiguration(ctx context.Context, raw []byte, createdAtEpoch int64, autogenInvalidReceiverAction notifier.InvalidReceiversAction) (remoteClient.UserGrafanaConfig, error) { @@ -317,7 +305,7 @@ func (am *Alertmanager) buildConfiguration(ctx context.Context, raw []byte, crea } // Decrypt the receivers in the configuration. - decryptedReceivers, err := notifier.DecryptedReceivers(c.AlertmanagerConfig.Receivers, decrypter(ctx, am.crypto)) + decryptedReceivers, err := notifier.DecryptedReceivers(c.AlertmanagerConfig.Receivers, notifier.DecryptIntegrationSettings(ctx, am.crypto)) if err != nil { return remoteClient.UserGrafanaConfig{}, fmt.Errorf("unable to decrypt receivers: %w", err) } @@ -619,7 +607,7 @@ func (am *Alertmanager) GetReceivers(ctx context.Context) ([]apimodels.Receiver, } func (am *Alertmanager) TestReceivers(ctx context.Context, c apimodels.TestReceiversConfigBodyParams) (*alertingNotify.TestReceiversResult, int, error) { - decryptedReceivers, err := notifier.DecryptedReceivers(c.Receivers, decrypter(ctx, am.crypto)) + decryptedReceivers, err := notifier.DecryptedReceivers(c.Receivers, notifier.DecryptIntegrationSettings(ctx, am.crypto)) if err != nil { return nil, 0, fmt.Errorf("failed to decrypt receivers: %w", err) } diff --git a/pkg/services/ngalert/remote/alertmanager_test.go b/pkg/services/ngalert/remote/alertmanager_test.go index d6f66756454..1a1d3943324 100644 --- a/pkg/services/ngalert/remote/alertmanager_test.go +++ b/pkg/services/ngalert/remote/alertmanager_test.go @@ -43,7 +43,6 @@ import ( "github.com/grafana/grafana/pkg/services/ngalert/notifier" "github.com/grafana/grafana/pkg/services/ngalert/remote/client" ngfakes "github.com/grafana/grafana/pkg/services/ngalert/tests/fakes" - "github.com/grafana/grafana/pkg/services/secrets" "github.com/grafana/grafana/pkg/services/secrets/database" "github.com/grafana/grafana/pkg/services/secrets/fakes" secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager" @@ -298,13 +297,7 @@ func TestIntegrationApplyConfig(t *testing.T) { var c apimodels.PostableUserConfig require.NoError(t, json.Unmarshal([]byte(testGrafanaConfigWithSecret), &c)) secretsService := secretsManager.SetupTestService(t, database.ProvideSecretsStore(db.InitTestDB(t))) - encryptedReceivers, err := notifier.EncryptedReceivers(c.AlertmanagerConfig.Receivers, func(payload string) (string, error) { - encrypted, err := secretsService.Encrypt(context.Background(), []byte(payload), secrets.WithoutScope()) - if err != nil { - return "", err - } - return base64.StdEncoding.EncodeToString(encrypted), nil - }) + encryptedReceivers, err := notifier.EncryptedReceivers(c.AlertmanagerConfig.Receivers, notifier.EncryptIntegrationSettings(context.Background(), secretsService)) c.AlertmanagerConfig.Receivers = encryptedReceivers require.NoError(t, err) @@ -462,13 +455,7 @@ func TestCompareAndSendConfiguration(t *testing.T) { // Create a config with correctly encrypted and encoded secrets. var inputCfg apimodels.PostableUserConfig require.NoError(t, json.Unmarshal([]byte(testGrafanaConfigWithSecret), &inputCfg)) - encryptedReceivers, err := notifier.EncryptedReceivers(inputCfg.AlertmanagerConfig.Receivers, func(payload string) (string, error) { - encrypted, err := secretsService.Encrypt(context.Background(), []byte(payload), secrets.WithoutScope()) - if err != nil { - return "", err - } - return base64.StdEncoding.EncodeToString(encrypted), nil - }) + encryptedReceivers, err := notifier.EncryptedReceivers(inputCfg.AlertmanagerConfig.Receivers, notifier.EncryptIntegrationSettings(context.Background(), secretsService)) inputCfg.AlertmanagerConfig.Receivers = encryptedReceivers require.NoError(t, err) testGrafanaConfigWithEncryptedSecret, err := json.Marshal(inputCfg) @@ -663,13 +650,7 @@ func Test_TestReceiversDecryptsSecureSettings(t *testing.T) { var inputCfg apimodels.PostableUserConfig require.NoError(t, json.Unmarshal([]byte(testGrafanaConfigWithSecret), &inputCfg)) - encryptedReceivers, err := notifier.EncryptedReceivers(inputCfg.AlertmanagerConfig.Receivers, func(payload string) (string, error) { - encrypted, err := secretsService.Encrypt(context.Background(), []byte(payload), secrets.WithoutScope()) - if err != nil { - return "", err - } - return base64.StdEncoding.EncodeToString(encrypted), nil - }) + encryptedReceivers, err := notifier.EncryptedReceivers(inputCfg.AlertmanagerConfig.Receivers, notifier.EncryptIntegrationSettings(context.Background(), secretsService)) inputCfg.AlertmanagerConfig.Receivers = encryptedReceivers require.NoError(t, err) @@ -1037,13 +1018,7 @@ func TestIntegrationRemoteAlertmanagerConfiguration(t *testing.T) { { postableCfg, err := notifier.Load([]byte(testGrafanaConfigWithSecret)) require.NoError(t, err) - encryptedReceivers, err := notifier.EncryptedReceivers(postableCfg.AlertmanagerConfig.Receivers, func(payload string) (string, error) { - encrypted, err := secretsService.Encrypt(context.Background(), []byte(payload), secrets.WithoutScope()) - if err != nil { - return "", err - } - return base64.StdEncoding.EncodeToString(encrypted), nil - }) + encryptedReceivers, err := notifier.EncryptedReceivers(postableCfg.AlertmanagerConfig.Receivers, notifier.EncryptIntegrationSettings(context.Background(), secretsService)) postableCfg.AlertmanagerConfig.Receivers = encryptedReceivers require.NoError(t, err)