diff --git a/pkg/services/ngalert/notifier/alertmanager.go b/pkg/services/ngalert/notifier/alertmanager.go index 264d8da6a60..abc44bd4d95 100644 --- a/pkg/services/ngalert/notifier/alertmanager.go +++ b/pkg/services/ngalert/notifier/alertmanager.go @@ -385,6 +385,10 @@ func (am *alertmanager) AppURL() string { // buildReceiverIntegrations builds a list of integration notifiers off of a receiver config. func (am *alertmanager) buildReceiverIntegrations(receiver *alertingNotify.APIReceiver, tmpl *alertingTemplates.Template) ([]*alertingNotify.Integration, error) { + err := patchNewSecureFields(context.Background(), receiver, am.decryptFn) + if err != nil { + return nil, err + } receiverCfg, err := alertingNotify.BuildReceiverConfiguration(context.Background(), receiver, am.decryptFn) if err != nil { return nil, err @@ -411,6 +415,52 @@ func (am *alertmanager) buildReceiverIntegrations(receiver *alertingNotify.APIRe return integrations, nil } +func patchNewSecureFields(ctx context.Context, api *alertingNotify.APIReceiver, decrypt alertingNotify.GetDecryptedValueFn) error { + for _, integration := range api.Integrations { + switch integration.Type { + case "dingding": + err := patchSettingsFromSecureSettings(ctx, integration, "url", decrypt) + if err != nil { + return err + } + } + } + return nil +} + +func patchSettingsFromSecureSettings(ctx context.Context, integration *alertingNotify.GrafanaIntegrationConfig, key string, decrypt alertingNotify.GetDecryptedValueFn) error { + var encrypted string + var ok bool + if encrypted, ok = integration.SecureSettings[key]; !ok { + return nil + } + decoded, err := decode(encrypted) + if err != nil { + return err + } + settings := map[string]any{} + err = json.Unmarshal(integration.Settings, &settings) + if err != nil { + return err + } + currentValue, ok := settings[key] + currentString := "" + if ok { + currentString, _ = currentValue.(string) + } + secretValue := decrypt(ctx, map[string][]byte{key: decoded}, key, currentString) + if secretValue == currentString { + return nil + } + settings[key] = secretValue + data, err := json.Marshal(settings) + if err != nil { + return err + } + integration.Settings = data + return nil +} + // PutAlerts receives the alerts and then sends them through the corresponding route based on whenever the alert has a receiver embedded or not func (am *alertmanager) PutAlerts(_ context.Context, postableAlerts apimodels.PostableAlerts) error { alerts := make(alertingNotify.PostableAlerts, 0, len(postableAlerts.PostableAlerts)) diff --git a/pkg/services/ngalert/notifier/channels_config/available_channels.go b/pkg/services/ngalert/notifier/channels_config/available_channels.go index dea5672f552..50891ad7b82 100644 --- a/pkg/services/ngalert/notifier/channels_config/available_channels.go +++ b/pkg/services/ngalert/notifier/channels_config/available_channels.go @@ -126,6 +126,7 @@ func GetAvailableNotifiers() []*NotifierPlugin { Placeholder: "https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxx", PropertyName: "url", Required: true, + Secure: true, }, { Label: "Message Type", diff --git a/pkg/services/ngalert/notifier/channels_config/available_channels_test.go b/pkg/services/ngalert/notifier/channels_config/available_channels_test.go index 40205e62ed2..c17c297ed0e 100644 --- a/pkg/services/ngalert/notifier/channels_config/available_channels_test.go +++ b/pkg/services/ngalert/notifier/channels_config/available_channels_test.go @@ -11,7 +11,7 @@ func TestGetSecretKeysForContactPointType(t *testing.T) { receiverType string expectedSecretFields []string }{ - {receiverType: "dingding", expectedSecretFields: []string{}}, + {receiverType: "dingding", expectedSecretFields: []string{"url"}}, {receiverType: "kafka", expectedSecretFields: []string{"password"}}, {receiverType: "email", expectedSecretFields: []string{}}, {receiverType: "pagerduty", expectedSecretFields: []string{"integrationKey"}}, diff --git a/pkg/services/ngalert/notifier/testreceivers.go b/pkg/services/ngalert/notifier/testreceivers.go index 1ca9cf9c42d..73c8a1a16d1 100644 --- a/pkg/services/ngalert/notifier/testreceivers.go +++ b/pkg/services/ngalert/notifier/testreceivers.go @@ -23,12 +23,17 @@ func (am *alertmanager) TestReceivers(ctx context.Context, c apimodels.TestRecei SecureSettings: gr.SecureSettings, }) } - receivers = append(receivers, &alertingNotify.APIReceiver{ + recv := &alertingNotify.APIReceiver{ ConfigReceiver: r.Receiver, GrafanaIntegrations: alertingNotify.GrafanaIntegrations{ Integrations: integrations, }, - }) + } + err := patchNewSecureFields(ctx, recv, am.decryptFn) + if err != nil { + return nil, 0, err + } + receivers = append(receivers, recv) } var alert *alertingNotify.TestReceiversConfigAlertParams if c.Alert != nil { diff --git a/pkg/tests/api/alerting/api_notification_channel_test.go b/pkg/tests/api/alerting/api_notification_channel_test.go index e98f0c2b27a..696e9909dcd 100644 --- a/pkg/tests/api/alerting/api_notification_channel_test.go +++ b/pkg/tests/api/alerting/api_notification_channel_test.go @@ -2146,10 +2146,8 @@ var expAlertmanagerConfigFromAPI = ` "name": "dingding_test", "type": "dingding", "disableResolveMessage": false, - "settings": { - "url": "http://CHANNEL_ADDR/dingding_recv/dingding_test" - }, - "secureFields": {} + "settings": {}, + "secureFields": {"url": true} } ] },