config: enforce HTTP or HTTPS URLs (#1567)
Signed-off-by: Simon Pasquier <spasquie@redhat.com>
This commit is contained in:
parent
e6c5c03c9e
commit
ce2f2ac380
|
@ -51,7 +51,7 @@ func (s Secret) MarshalJSON() ([]byte, error) {
|
|||
return json.Marshal("<secret>")
|
||||
}
|
||||
|
||||
// URL is a custom type that allows validation at configuration load time.
|
||||
// URL is a custom type that represents an HTTP or HTTPS URL and allows validation at configuration load time.
|
||||
type URL struct {
|
||||
*url.URL
|
||||
}
|
||||
|
@ -76,11 +76,11 @@ func (u *URL) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||
if err := unmarshal(&s); err != nil {
|
||||
return err
|
||||
}
|
||||
urlp, err := url.Parse(s)
|
||||
urlp, err := parseURL(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.URL = urlp
|
||||
u.URL = urlp.URL
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -98,11 +98,11 @@ func (u *URL) UnmarshalJSON(data []byte) error {
|
|||
if err := json.Unmarshal(data, &s); err != nil {
|
||||
return err
|
||||
}
|
||||
urlp, err := url.Parse(s)
|
||||
urlp, err := parseURL(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.URL = urlp
|
||||
u.URL = urlp.URL
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -434,11 +434,25 @@ var DefaultGlobalConfig = GlobalConfig{
|
|||
}
|
||||
|
||||
func mustParseURL(s string) *URL {
|
||||
u, err := url.Parse(s)
|
||||
u, err := parseURL(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &URL{u}
|
||||
return u
|
||||
}
|
||||
|
||||
func parseURL(s string) (*URL, error) {
|
||||
u, err := url.Parse(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if u.Scheme != "http" && u.Scheme != "https" {
|
||||
return nil, fmt.Errorf("unsupported scheme %q for URL", u.Scheme)
|
||||
}
|
||||
if u.Host == "" {
|
||||
return nil, fmt.Errorf("missing host for URL")
|
||||
}
|
||||
return &URL{u}, nil
|
||||
}
|
||||
|
||||
// GlobalConfig defines configuration parameters that are valid globally
|
||||
|
|
|
@ -369,7 +369,28 @@ func TestUnmarshalURL(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestUnmarshalInvalidURL(t *testing.T) {
|
||||
b := []byte(`"://example.com"`)
|
||||
for _, b := range [][]byte{
|
||||
[]byte(`"://example.com"`),
|
||||
[]byte(`"http:example.com"`),
|
||||
[]byte(`"telnet://example.com"`),
|
||||
} {
|
||||
var u URL
|
||||
|
||||
err := json.Unmarshal(b, &u)
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error unmarshalling %q from JSON", string(b))
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(b, &u)
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error unmarshalling %q from YAML", string(b))
|
||||
}
|
||||
t.Logf("%s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalRelativeURL(t *testing.T) {
|
||||
b := []byte(`"/home"`)
|
||||
var u URL
|
||||
|
||||
err := json.Unmarshal(b, &u)
|
||||
|
@ -383,22 +404,16 @@ func TestUnmarshalInvalidURL(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestJSONUnmarshalMarshaled(t *testing.T) {
|
||||
func TestJSONUnmarshal(t *testing.T) {
|
||||
c, _, err := LoadFile("testdata/conf.good.yml")
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing %s: %s", "testdata/conf.good.yml", err)
|
||||
}
|
||||
|
||||
plainCfg, err := json.Marshal(c)
|
||||
_, err = json.Marshal(c)
|
||||
if err != nil {
|
||||
t.Fatal("JSON Marshaling failed:", err)
|
||||
}
|
||||
|
||||
cfg := Config{}
|
||||
err = json.Unmarshal(plainCfg, &cfg)
|
||||
if err != nil {
|
||||
t.Fatal("JSON Unmarshaling failed:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmptyFieldsAndRegex(t *testing.T) {
|
||||
|
|
|
@ -6,7 +6,7 @@ global:
|
|||
smtp_hello: ''
|
||||
hipchat_auth_token: 'mysecret'
|
||||
hipchat_api_url: 'https://hipchat.foobar.org/'
|
||||
slack_api_url: 'mysecret'
|
||||
slack_api_url: 'https://slack.com/webhook'
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue