Use gcpConfig type to keep configuration urls.

Fixes #67
This commit is contained in:
Mariano Cano 2019-04-23 14:33:36 -07:00
parent 7e53b28320
commit fb6321fb2c
2 changed files with 34 additions and 13 deletions

View file

@ -17,10 +17,10 @@ import (
) )
// gcpCertsURL is the url that servers Google OAuth2 public keys. // gcpCertsURL is the url that servers Google OAuth2 public keys.
var gcpCertsURL = "https://www.googleapis.com/oauth2/v3/certs" const gcpCertsURL = "https://www.googleapis.com/oauth2/v3/certs"
// gcpIdentityURL is the base url for the identity document in GCP. // gcpIdentityURL is the base url for the identity document in GCP.
var gcpIdentityURL = "http://metadata/computeMetadata/v1/instance/service-accounts/default/identity" const gcpIdentityURL = "http://metadata/computeMetadata/v1/instance/service-accounts/default/identity"
// gcpPayload extends jwt.Claims with custom GCP attributes. // gcpPayload extends jwt.Claims with custom GCP attributes.
type gcpPayload struct { type gcpPayload struct {
@ -45,6 +45,18 @@ type gcpComputeEnginePayload struct {
LicenseID []string `json:"license_id"` LicenseID []string `json:"license_id"`
} }
type gcpConfig struct {
CertsURL string
IdentityURL string
}
func newGCPConfig() *gcpConfig {
return &gcpConfig{
CertsURL: gcpCertsURL,
IdentityURL: gcpIdentityURL,
}
}
// GCP is the provisioner that supports identity tokens created by the Google // GCP is the provisioner that supports identity tokens created by the Google
// Cloud Platform metadata API. // Cloud Platform metadata API.
type GCP struct { type GCP struct {
@ -53,6 +65,7 @@ type GCP struct {
ServiceAccounts []string `json:"serviceAccounts"` ServiceAccounts []string `json:"serviceAccounts"`
Claims *Claims `json:"claims,omitempty"` Claims *Claims `json:"claims,omitempty"`
claimer *Claimer claimer *Claimer
config *gcpConfig
keyStore *keyStore keyStore *keyStore
} }
@ -101,11 +114,14 @@ func (p *GCP) GetEncryptedKey() (kid string, key string, ok bool) {
// GetIdentityURL returns the url that generates the GCP token. // GetIdentityURL returns the url that generates the GCP token.
func (p *GCP) GetIdentityURL() string { func (p *GCP) GetIdentityURL() string {
// Initialize config if required
p.assertConfig()
q := url.Values{} q := url.Values{}
q.Add("audience", p.GetID()) q.Add("audience", p.GetID())
q.Add("format", "full") q.Add("format", "full")
q.Add("licenses", "FALSE") q.Add("licenses", "FALSE")
return fmt.Sprintf("%s?%s", gcpIdentityURL, q.Encode()) return fmt.Sprintf("%s?%s", p.config.IdentityURL, q.Encode())
} }
// GetIdentityToken does an HTTP request to the identity url. // GetIdentityToken does an HTTP request to the identity url.
@ -139,12 +155,14 @@ func (p *GCP) Init(config Config) error {
case p.Name == "": case p.Name == "":
return errors.New("provisioner name cannot be empty") return errors.New("provisioner name cannot be empty")
} }
// Initialize config
p.assertConfig()
// Update claims with global ones // Update claims with global ones
if p.claimer, err = NewClaimer(p.Claims, config.Claims); err != nil { if p.claimer, err = NewClaimer(p.Claims, config.Claims); err != nil {
return err return err
} }
// Initialize key store // Initialize key store
p.keyStore, err = newKeyStore(gcpCertsURL) p.keyStore, err = newKeyStore(p.config.CertsURL)
if err != nil { if err != nil {
return err return err
} }
@ -188,6 +206,13 @@ func (p *GCP) AuthorizeRevoke(token string) error {
return errors.New("revoke is not supported on a GCP provisioner") return errors.New("revoke is not supported on a GCP provisioner")
} }
// assertConfig initializes the config if it has not been initialized.
func (p *GCP) assertConfig() {
if p.config == nil {
p.config = newGCPConfig()
}
}
// authorizeToken performs common jwt authorization actions and returns the // authorizeToken performs common jwt authorization actions and returns the
// claims for case specific downstream parsing. // claims for case specific downstream parsing.
// e.g. a Sign request will auth/validate different fields than a Revoke request. // e.g. a Sign request will auth/validate different fields than a Revoke request.

View file

@ -15,11 +15,6 @@ import (
"github.com/smallstep/assert" "github.com/smallstep/assert"
) )
func resetGoogleVars() {
gcpCertsURL = "https://www.googleapis.com/oauth2/v3/certs"
gcpIdentityURL = "http://metadata/computeMetadata/v1/instance/service-accounts/default/identity"
}
func TestGCP_Getters(t *testing.T) { func TestGCP_Getters(t *testing.T) {
p, err := generateGCP() p, err := generateGCP()
assert.FatalError(t, err) assert.FatalError(t, err)
@ -91,7 +86,6 @@ func TestGCP_GetTokenID(t *testing.T) {
func TestGCP_GetIdentityToken(t *testing.T) { func TestGCP_GetIdentityToken(t *testing.T) {
p1, err := generateGCP() p1, err := generateGCP()
assert.FatalError(t, err) assert.FatalError(t, err)
defer resetGoogleVars()
t1, err := generateGCPToken(p1.ServiceAccounts[0], t1, err := generateGCPToken(p1.ServiceAccounts[0],
"https://accounts.google.com", p1.GetID(), "https://accounts.google.com", p1.GetID(),
@ -123,7 +117,7 @@ func TestGCP_GetIdentityToken(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
gcpIdentityURL = tt.identityURL tt.gcp.config.IdentityURL = tt.identityURL
got, err := tt.gcp.GetIdentityToken() got, err := tt.gcp.GetIdentityToken()
t.Log(err) t.Log(err)
if (err != nil) != tt.wantErr { if (err != nil) != tt.wantErr {
@ -140,7 +134,6 @@ func TestGCP_GetIdentityToken(t *testing.T) {
func TestGCP_Init(t *testing.T) { func TestGCP_Init(t *testing.T) {
srv := generateJWKServer(2) srv := generateJWKServer(2)
defer srv.Close() defer srv.Close()
defer resetGoogleVars()
config := Config{ config := Config{
Claims: globalProvisionerClaims, Claims: globalProvisionerClaims,
@ -174,12 +167,15 @@ func TestGCP_Init(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
gcpCertsURL = tt.args.certsURL
p := &GCP{ p := &GCP{
Type: tt.fields.Type, Type: tt.fields.Type,
Name: tt.fields.Name, Name: tt.fields.Name,
ServiceAccounts: tt.fields.ServiceAccounts, ServiceAccounts: tt.fields.ServiceAccounts,
Claims: tt.fields.Claims, Claims: tt.fields.Claims,
config: &gcpConfig{
CertsURL: tt.args.certsURL,
IdentityURL: gcpIdentityURL,
},
} }
if err := p.Init(tt.args.config); (err != nil) != tt.wantErr { if err := p.Init(tt.args.config); (err != nil) != tt.wantErr {
t.Errorf("GCP.Init() error = %v, wantErr %v", err, tt.wantErr) t.Errorf("GCP.Init() error = %v, wantErr %v", err, tt.wantErr)