Do not marshal secrets in URL's

Signed-off-by: Julien Pivotto <roidelapluie@inuits.eu>
diff --git a/config/http_config.go b/config/http_config.go
index 6c0c033..f47892d 100644
--- a/config/http_config.go
+++ b/config/http_config.go
@@ -110,11 +110,25 @@
 // MarshalYAML implements the yaml.Marshaler interface for URLs.
 func (u URL) MarshalYAML() (interface{}, error) {
 	if u.URL != nil {
-		return u.String(), nil
+		return u.Redacted(), nil
 	}
 	return nil, nil
 }
 
+// Redacted returns the URL but replaces any password with "xxxxx".
+func (u URL) Redacted() string {
+	if u.URL == nil {
+		return ""
+	}
+
+	ru := *u.URL
+	if _, ok := ru.User.Password(); ok {
+		// We can not use secretToken because it would be escaped.
+		ru.User = url.UserPassword(ru.User.Username(), "xxxxx")
+	}
+	return ru.String()
+}
+
 // UnmarshalJSON implements the json.Marshaler interface for URL.
 func (u *URL) UnmarshalJSON(data []byte) error {
 	var s string
diff --git a/config/http_config_test.go b/config/http_config_test.go
index 5ec3229..689bbde 100644
--- a/config/http_config_test.go
+++ b/config/http_config_test.go
@@ -1418,3 +1418,19 @@
 		t.Fatalf("URL not properly unmarshaled in YAML, got '%s'", u.String())
 	}
 }
+
+func TestMarshalURLWithSecret(t *testing.T) {
+	var u URL
+	err := yaml.Unmarshal([]byte("http://foo:bar@example.com"), &u)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	b, err := yaml.Marshal(u)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if strings.TrimSpace(string(b)) != "http://foo:xxxxx@example.com" {
+		t.Fatalf("URL not properly marshaled in YAML, got '%s'", string(b))
+	}
+}