Skip to content

Commit 4f10742

Browse files
author
Walther Lee
committed
update config to use MarshalSecretValue
Signed-off-by: Walther Lee <[email protected]>
1 parent 0d28327 commit 4f10742

File tree

2 files changed

+90
-2
lines changed

2 files changed

+90
-2
lines changed

config/config.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ const secretToken = "<secret>"
3939

4040
var secretTokenJSON string
4141

42+
// MarshalSecretValue if set to true will expose Secret type
43+
// through the marshal interfaces. Useful for outside projects
44+
// that load and marshal the Alertmanager config.
45+
var MarshalSecretValue bool = commoncfg.MarshalSecretValue
46+
4247
func init() {
4348
b, err := json.Marshal(secretToken)
4449
if err != nil {
@@ -52,6 +57,9 @@ type Secret string
5257

5358
// MarshalYAML implements the yaml.Marshaler interface for Secret.
5459
func (s Secret) MarshalYAML() (interface{}, error) {
60+
if MarshalSecretValue {
61+
return string(s), nil
62+
}
5563
if s != "" {
5664
return secretToken, nil
5765
}
@@ -66,6 +74,12 @@ func (s *Secret) UnmarshalYAML(unmarshal func(interface{}) error) error {
6674

6775
// MarshalJSON implements the json.Marshaler interface for Secret.
6876
func (s Secret) MarshalJSON() ([]byte, error) {
77+
if MarshalSecretValue {
78+
return json.Marshal(string(s))
79+
}
80+
if len(s) == 0 {
81+
return json.Marshal("")
82+
}
6983
return json.Marshal(secretToken)
7084
}
7185

@@ -130,6 +144,9 @@ type SecretURL URL
130144
// MarshalYAML implements the yaml.Marshaler interface for SecretURL.
131145
func (s SecretURL) MarshalYAML() (interface{}, error) {
132146
if s.URL != nil {
147+
if MarshalSecretValue {
148+
return s.URL.String(), nil
149+
}
133150
return secretToken, nil
134151
}
135152
return nil, nil
@@ -153,6 +170,12 @@ func (s *SecretURL) UnmarshalYAML(unmarshal func(interface{}) error) error {
153170

154171
// MarshalJSON implements the json.Marshaler interface for SecretURL.
155172
func (s SecretURL) MarshalJSON() ([]byte, error) {
173+
if s.URL == nil {
174+
return json.Marshal("")
175+
}
176+
if MarshalSecretValue {
177+
return json.Marshal(s.URL.String())
178+
}
156179
return json.Marshal(secretToken)
157180
}
158181

@@ -167,6 +190,9 @@ func (s *SecretURL) UnmarshalJSON(data []byte) error {
167190
}
168191
// Redact the secret URL in case of errors
169192
if err := json.Unmarshal(data, (*URL)(s)); err != nil {
193+
if MarshalSecretValue {
194+
return err
195+
}
170196
return errors.New(strings.ReplaceAll(err.Error(), string(data), "[REDACTED]"))
171197
}
172198

config/config_test.go

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,22 @@ func TestHideConfigSecrets(t *testing.T) {
521521
}
522522
}
523523

524+
func TestShowMarshalSecretValues(t *testing.T) {
525+
MarshalSecretValue = true
526+
defer func() { MarshalSecretValue = false }()
527+
528+
c, err := LoadFile("testdata/conf.good.yml")
529+
if err != nil {
530+
t.Fatalf("Error parsing %s: %s", "testdata/conf.good.yml", err)
531+
}
532+
533+
// String method must reveal authentication credentials.
534+
s := c.String()
535+
if strings.Count(s, "<secret>") > 0 || !strings.Contains(s, "mysecret") {
536+
t.Fatal("config's String method must reveal authentication credentials when MarshalSecretValue = true.")
537+
}
538+
}
539+
524540
func TestJSONMarshal(t *testing.T) {
525541
c, err := LoadFile("testdata/conf.good.yml")
526542
if err != nil {
@@ -533,7 +549,7 @@ func TestJSONMarshal(t *testing.T) {
533549
}
534550
}
535551

536-
func TestJSONMarshalSecret(t *testing.T) {
552+
func TestJSONMarshalHideSecret(t *testing.T) {
537553
test := struct {
538554
S Secret
539555
}{
@@ -550,7 +566,24 @@ func TestJSONMarshalSecret(t *testing.T) {
550566
require.Equal(t, "{\"S\":\"\\u003csecret\\u003e\"}", string(c), "Secret not properly elided.")
551567
}
552568

553-
func TestMarshalSecretURL(t *testing.T) {
569+
func TestJSONMarshalShowSecret(t *testing.T) {
570+
MarshalSecretValue = true
571+
defer func() { MarshalSecretValue = false }()
572+
573+
test := struct {
574+
S Secret
575+
}{
576+
S: Secret("test"),
577+
}
578+
579+
c, err := json.Marshal(test)
580+
if err != nil {
581+
t.Fatal(err)
582+
}
583+
require.Equal(t, "{\"S\":\"test\"}", string(c), "config's String method must reveal authentication credentials when MarshalSecretValue = true.")
584+
}
585+
586+
func TestJSONMarshalHideSecretURL(t *testing.T) {
554587
urlp, err := url.Parse("http://example.com/")
555588
if err != nil {
556589
t.Fatal(err)
@@ -584,6 +617,23 @@ func TestMarshalSecretURL(t *testing.T) {
584617
}
585618
}
586619

620+
func TestJSONMarshalShowSecretURL(t *testing.T) {
621+
MarshalSecretValue = true
622+
defer func() { MarshalSecretValue = false }()
623+
624+
urlp, err := url.Parse("http://example.com/")
625+
if err != nil {
626+
t.Fatal(err)
627+
}
628+
u := &SecretURL{urlp}
629+
630+
c, err := json.Marshal(u)
631+
if err != nil {
632+
t.Fatal(err)
633+
}
634+
require.Equal(t, "\"http://example.com/\"", string(c), "config's String method must reveal authentication credentials when MarshalSecretValue = true.")
635+
}
636+
587637
func TestUnmarshalSecretURL(t *testing.T) {
588638
b := []byte(`"http://example.com/se cret"`)
589639
var u SecretURL
@@ -611,6 +661,18 @@ func TestHideSecretURL(t *testing.T) {
611661
require.NotContains(t, err.Error(), "wrongurl")
612662
}
613663

664+
func TestShowMarshalSecretURL(t *testing.T) {
665+
MarshalSecretValue = true
666+
defer func() { MarshalSecretValue = false }()
667+
668+
b := []byte(`"://wrongurl/"`)
669+
var u SecretURL
670+
671+
err := json.Unmarshal(b, &u)
672+
require.Error(t, err)
673+
require.Contains(t, err.Error(), "wrongurl")
674+
}
675+
614676
func TestMarshalURL(t *testing.T) {
615677
for name, tc := range map[string]struct {
616678
input *URL

0 commit comments

Comments
 (0)