@@ -30,11 +30,10 @@ import (
3030// ClientCredentialsFlow takes care of the mechanics needed for getting an access
3131// token using the OAuth 2.0 "Client Credentials Flow"
3232type ClientCredentialsFlow struct {
33- options ClientCredentialsFlowOptions
34- oidcWellKnownEndpoints OIDCWellKnownEndpoints
35- keyfile * KeyFile
36- exchanger ClientCredentialsExchanger
37- clock clock.Clock
33+ options ClientCredentialsFlowOptions
34+ exchanger ClientCredentialsExchanger
35+ grantProvider GrantProvider
36+ clock clock.Clock
3837}
3938
4039// ClientCredentialsProvider abstracts getting client credentials
@@ -47,29 +46,24 @@ type ClientCredentialsExchanger interface {
4746 ExchangeClientCredentials (req ClientCredentialsExchangeRequest ) (* TokenResult , error )
4847}
4948
49+ // GrantProvider abstracts the creation of authorization grants from credentials
50+ type GrantProvider interface {
51+ GetGrant (audience string , options * ClientCredentialsFlowOptions ) (* AuthorizationGrant , error )
52+ }
53+
5054type ClientCredentialsFlowOptions struct {
5155 KeyFile string
5256 AdditionalScopes []string
5357}
5458
55- func newClientCredentialsFlow (
56- options ClientCredentialsFlowOptions ,
57- keyfile * KeyFile ,
58- oidcWellKnownEndpoints OIDCWellKnownEndpoints ,
59- exchanger ClientCredentialsExchanger ,
60- clock clock.Clock ) * ClientCredentialsFlow {
61- return & ClientCredentialsFlow {
62- options : options ,
63- oidcWellKnownEndpoints : oidcWellKnownEndpoints ,
64- keyfile : keyfile ,
65- exchanger : exchanger ,
66- clock : clock ,
67- }
59+ // DefaultGrantProvider provides authorization grants by loading credentials from a key file
60+ type DefaultGrantProvider struct {
6861}
6962
70- // NewDefaultClientCredentialsFlow provides an easy way to build up a default
71- // client credentials flow with all the correct configuration.
72- func NewDefaultClientCredentialsFlow (options ClientCredentialsFlowOptions ) (* ClientCredentialsFlow , error ) {
63+ // GetGrant creates an authorization grant by loading credentials from the key file and
64+ // merging the scopes from both the options and the key file configuration
65+ func (p * DefaultGrantProvider ) GetGrant (audience string , options * ClientCredentialsFlowOptions ) (
66+ * AuthorizationGrant , error ) {
7367 credsProvider := NewClientCredentialsProviderFromKeyFile (options .KeyFile )
7468 keyFile , err := credsProvider .GetClientCredentials ()
7569 if err != nil {
@@ -80,39 +74,58 @@ func NewDefaultClientCredentialsFlow(options ClientCredentialsFlowOptions) (*Cli
8074 if err != nil {
8175 return nil , err
8276 }
77+ // Merge the scopes of the options AdditionalScopes with the scopes read from the keyFile config
78+ var scopesToAdd []string
79+ if len (options .AdditionalScopes ) > 0 {
80+ scopesToAdd = append (scopesToAdd , options .AdditionalScopes ... )
81+ }
82+
83+ if keyFile .Scope != "" {
84+ scopesSplit := strings .Fields (keyFile .Scope )
85+ scopesToAdd = append (scopesToAdd , scopesSplit ... )
86+ }
87+
88+ return & AuthorizationGrant {
89+ Type : GrantTypeClientCredentials ,
90+ Audience : audience ,
91+ ClientID : keyFile .ClientID ,
92+ ClientCredentials : keyFile ,
93+ TokenEndpoint : wellKnownEndpoints .TokenEndpoint ,
94+ Scopes : scopesToAdd ,
95+ }, nil
96+ }
97+
98+ func newClientCredentialsFlow (
99+ options ClientCredentialsFlowOptions ,
100+ exchanger ClientCredentialsExchanger ,
101+ grantProvider GrantProvider ,
102+ clock clock.Clock ) * ClientCredentialsFlow {
103+ return & ClientCredentialsFlow {
104+ options : options ,
105+ exchanger : exchanger ,
106+ grantProvider : grantProvider ,
107+ clock : clock ,
108+ }
109+ }
110+
111+ // NewDefaultClientCredentialsFlow provides an easy way to build up a default
112+ // client credentials flow with all the correct configuration.
113+ func NewDefaultClientCredentialsFlow (options ClientCredentialsFlowOptions ) (* ClientCredentialsFlow , error ) {
83114
84115 tokenRetriever := NewTokenRetriever (& http.Client {})
85116 return newClientCredentialsFlow (
86117 options ,
87- keyFile ,
88- * wellKnownEndpoints ,
89118 tokenRetriever ,
119+ & DefaultGrantProvider {},
90120 clock.RealClock {}), nil
91121}
92122
93123var _ Flow = & ClientCredentialsFlow {}
94124
95125func (c * ClientCredentialsFlow ) Authorize (audience string ) (* AuthorizationGrant , error ) {
96- var err error
97-
98- // Merge the scopes of the options AdditionalScopes with the scopes read from the keyFile config
99- var scopesToAdd []string
100- if len (c .options .AdditionalScopes ) > 0 {
101- scopesToAdd = append (scopesToAdd , c .options .AdditionalScopes ... )
102- }
103-
104- if c .keyfile .Scope != "" {
105- scopesSplit := strings .Split (c .keyfile .Scope , " " )
106- scopesToAdd = append (scopesToAdd , scopesSplit ... )
107- }
108-
109- grant := & AuthorizationGrant {
110- Type : GrantTypeClientCredentials ,
111- Audience : audience ,
112- ClientID : c .keyfile .ClientID ,
113- ClientCredentials : c .keyfile ,
114- TokenEndpoint : c .oidcWellKnownEndpoints .TokenEndpoint ,
115- Scopes : scopesToAdd ,
126+ grant , err := c .grantProvider .GetGrant (audience , & c .options )
127+ if err != nil {
128+ return nil , err
116129 }
117130
118131 // test the credentials and obtain an initial access token
0 commit comments