add Provisioner config validation

This commit is contained in:
max furman 2018-10-08 23:25:18 -07:00
parent 0e904989d2
commit f1dc00c810
2 changed files with 92 additions and 13 deletions

View file

@ -59,6 +59,22 @@ type Provisioner struct {
EncryptedKey string `json:"encryptedKey,omitempty"` EncryptedKey string `json:"encryptedKey,omitempty"`
} }
// Validate validates a provisioner.
func (p *Provisioner) Validate() error {
switch {
case p.Issuer == "":
return errors.New("provisioner issuer cannot be empty")
case p.Type == "":
return errors.New("provisioner type cannot be empty")
case p.Key == nil:
return errors.New("provisioner key cannot be empty")
}
return nil
}
// Config represents the CA configuration and it's mapped to a JSON object. // Config represents the CA configuration and it's mapped to a JSON object.
type Config struct { type Config struct {
Root string `json:"root"` Root string `json:"root"`
@ -83,17 +99,22 @@ type AuthConfig struct {
// Validate validates the authority configuration. // Validate validates the authority configuration.
func (c *AuthConfig) Validate() error { func (c *AuthConfig) Validate() error {
switch { if c == nil {
case c == nil:
return errors.New("authority cannot be undefined") return errors.New("authority cannot be undefined")
case len(c.Provisioners) == 0:
return errors.New("authority.provisioners cannot be empty")
default:
if c.Template == nil {
c.Template = &x509util.ASN1DN{}
}
return nil
} }
if len(c.Provisioners) == 0 {
return errors.New("authority.provisioners cannot be empty")
}
for _, p := range c.Provisioners {
err := p.Validate()
if err != nil {
return err
}
}
if c.Template == nil {
c.Template = &x509util.ASN1DN{}
}
return nil
} }
// LoadConfiguration parses the given filename in JSON format and returns the // LoadConfiguration parses the given filename in JSON format and returns the

View file

@ -8,8 +8,55 @@ import (
"github.com/smallstep/cli/crypto/tlsutil" "github.com/smallstep/cli/crypto/tlsutil"
"github.com/smallstep/cli/crypto/x509util" "github.com/smallstep/cli/crypto/x509util"
stepJOSE "github.com/smallstep/cli/jose" stepJOSE "github.com/smallstep/cli/jose"
jose "gopkg.in/square/go-jose.v2"
) )
func TestProvisionerValidate(t *testing.T) {
type ProvisionerValidateTest struct {
p *Provisioner
err error
}
tests := map[string]func(*testing.T) ProvisionerValidateTest{
"fail-empty-issuer": func(t *testing.T) ProvisionerValidateTest {
return ProvisionerValidateTest{
p: &Provisioner{},
err: errors.New("provisioner issuer cannot be empty"),
}
},
"fail-empty-type": func(t *testing.T) ProvisionerValidateTest {
return ProvisionerValidateTest{
p: &Provisioner{Issuer: "foo"},
err: errors.New("provisioner type cannot be empty"),
}
},
"fail-empty-key": func(t *testing.T) ProvisionerValidateTest {
return ProvisionerValidateTest{
p: &Provisioner{Issuer: "foo", Type: "bar"},
err: errors.New("provisioner key cannot be empty"),
}
},
"ok": func(t *testing.T) ProvisionerValidateTest {
return ProvisionerValidateTest{
p: &Provisioner{Issuer: "foo", Type: "bar", Key: &jose.JSONWebKey{}},
}
},
}
for name, get := range tests {
t.Run(name, func(t *testing.T) {
tc := get(t)
err := tc.p.Validate()
if err != nil {
if assert.NotNil(t, tc.err) {
assert.Equals(t, tc.err.Error(), err.Error())
}
} else {
assert.Nil(t, tc.err)
}
})
}
}
func TestConfigValidate(t *testing.T) { func TestConfigValidate(t *testing.T) {
maxjwk, err := stepJOSE.ParseKey("testdata/secrets/max_pub.jwk") maxjwk, err := stepJOSE.ParseKey("testdata/secrets/max_pub.jwk")
assert.FatalError(t, err) assert.FatalError(t, err)
@ -233,19 +280,30 @@ func TestAuthConfigValidate(t *testing.T) {
err error err error
} }
tests := map[string]func(*testing.T) AuthConfigValidateTest{ tests := map[string]func(*testing.T) AuthConfigValidateTest{
"nil": func(t *testing.T) AuthConfigValidateTest { "fail-nil-authconfig": func(t *testing.T) AuthConfigValidateTest {
return AuthConfigValidateTest{ return AuthConfigValidateTest{
ac: nil, ac: nil,
err: errors.New("authority cannot be undefined"), err: errors.New("authority cannot be undefined"),
} }
}, },
"empty-provisioners": func(t *testing.T) AuthConfigValidateTest { "fail-empty-provisioners": func(t *testing.T) AuthConfigValidateTest {
return AuthConfigValidateTest{ return AuthConfigValidateTest{
ac: &AuthConfig{}, ac: &AuthConfig{},
err: errors.New("authority.provisioners cannot be empty"), err: errors.New("authority.provisioners cannot be empty"),
} }
}, },
"empty-asn1dn-template": func(t *testing.T) AuthConfigValidateTest { "fail-invalid-provisioners": func(t *testing.T) AuthConfigValidateTest {
return AuthConfigValidateTest{
ac: &AuthConfig{
Provisioners: []*Provisioner{
&Provisioner{Issuer: "foo", Type: "bar", Key: &jose.JSONWebKey{}},
&Provisioner{Issuer: "foo", Key: &jose.JSONWebKey{}},
},
},
err: errors.New("provisioner type cannot be empty"),
}
},
"ok-empty-asn1dn-template": func(t *testing.T) AuthConfigValidateTest {
return AuthConfigValidateTest{ return AuthConfigValidateTest{
ac: &AuthConfig{ ac: &AuthConfig{
Provisioners: p, Provisioners: p,
@ -253,7 +311,7 @@ func TestAuthConfigValidate(t *testing.T) {
asn1dn: x509util.ASN1DN{}, asn1dn: x509util.ASN1DN{},
} }
}, },
"custom-asn1dn": func(t *testing.T) AuthConfigValidateTest { "ok-custom-asn1dn": func(t *testing.T) AuthConfigValidateTest {
return AuthConfigValidateTest{ return AuthConfigValidateTest{
ac: &AuthConfig{ ac: &AuthConfig{
Provisioners: p, Provisioners: p,