feat: add service account impersonation support

The impersonated_service_account type in the JSON configuration file is taken into account. source_credentials field in the JSON is now supported.

Fixes #515
This commit is contained in:
guillaume blaquiere 2021-08-23 10:43:18 +02:00
parent 2bc19b1117
commit a3dd13af1f
1 changed files with 24 additions and 3 deletions

View File

@ -92,9 +92,10 @@ func JWTConfigFromJSON(jsonKey []byte, scope ...string) (*jwt.Config, error) {
// JSON key file types.
const (
serviceAccountKey = "service_account"
userCredentialsKey = "authorized_user"
externalAccountKey = "external_account"
serviceAccountKey = "service_account"
userCredentialsKey = "authorized_user"
externalAccountKey = "external_account"
impersonatedServiceAccount = "impersonated_service_account"
)
// credentialsFile is the unmarshalled representation of a credentials file.
@ -123,6 +124,9 @@ type credentialsFile struct {
ServiceAccountImpersonationURL string `json:"service_account_impersonation_url"`
CredentialSource externalaccount.CredentialSource `json:"credential_source"`
QuotaProjectID string `json:"quota_project_id"`
// Service account impersonation
SourceCredentials *credentialsFile `json:"source_credentials"`
}
func (f *credentialsFile) jwtConfig(scopes []string, subject string) *jwt.Config {
@ -178,6 +182,23 @@ func (f *credentialsFile) tokenSource(ctx context.Context, params CredentialsPar
Scopes: params.Scopes,
}
return cfg.TokenSource(ctx)
case impersonatedServiceAccount:
if f.SourceCredentials == nil {
return nil, errors.New("missing 'source_credentials' field in credentials")
}
sourceToken, err := f.SourceCredentials.tokenSource(ctx, params)
if err != nil {
return nil, err
}
imp := externalaccount.ImpersonateTokenSource{
Ctx: ctx,
Url: f.ServiceAccountImpersonationURL,
Scopes: params.Scopes,
Ts: oauth2.ReuseTokenSource(nil, sourceToken),
// Delegates?? -> I don't know how to manage and how to use them here
}
return oauth2.ReuseTokenSource(nil, imp), nil
case "":
return nil, errors.New("missing 'type' field in credentials")
default: