forked from Mirrors/oauth2
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:
parent
2bc19b1117
commit
a3dd13af1f
|
@ -92,9 +92,10 @@ func JWTConfigFromJSON(jsonKey []byte, scope ...string) (*jwt.Config, error) {
|
||||||
|
|
||||||
// JSON key file types.
|
// JSON key file types.
|
||||||
const (
|
const (
|
||||||
serviceAccountKey = "service_account"
|
serviceAccountKey = "service_account"
|
||||||
userCredentialsKey = "authorized_user"
|
userCredentialsKey = "authorized_user"
|
||||||
externalAccountKey = "external_account"
|
externalAccountKey = "external_account"
|
||||||
|
impersonatedServiceAccount = "impersonated_service_account"
|
||||||
)
|
)
|
||||||
|
|
||||||
// credentialsFile is the unmarshalled representation of a credentials file.
|
// credentialsFile is the unmarshalled representation of a credentials file.
|
||||||
|
@ -123,6 +124,9 @@ type credentialsFile struct {
|
||||||
ServiceAccountImpersonationURL string `json:"service_account_impersonation_url"`
|
ServiceAccountImpersonationURL string `json:"service_account_impersonation_url"`
|
||||||
CredentialSource externalaccount.CredentialSource `json:"credential_source"`
|
CredentialSource externalaccount.CredentialSource `json:"credential_source"`
|
||||||
QuotaProjectID string `json:"quota_project_id"`
|
QuotaProjectID string `json:"quota_project_id"`
|
||||||
|
|
||||||
|
// Service account impersonation
|
||||||
|
SourceCredentials *credentialsFile `json:"source_credentials"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *credentialsFile) jwtConfig(scopes []string, subject string) *jwt.Config {
|
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,
|
Scopes: params.Scopes,
|
||||||
}
|
}
|
||||||
return cfg.TokenSource(ctx)
|
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 "":
|
case "":
|
||||||
return nil, errors.New("missing 'type' field in credentials")
|
return nil, errors.New("missing 'type' field in credentials")
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in New Issue