@@ -18,17 +18,27 @@ import (
18
18
19
19
"github.com/pkg/browser"
20
20
"golang.org/x/oauth2"
21
+ "golang.org/x/oauth2/clientcredentials"
21
22
22
23
"github.com/snyk/go-application-framework/pkg/configuration"
23
24
)
24
25
25
26
const (
26
- CONFIG_KEY_OAUTH_TOKEN string = "INTERNAL_OAUTH_TOKEN_STORAGE"
27
- OAUTH_CLIENT_ID string = "b56d4c2e-b9e1-4d27-8773-ad47eafb0956"
28
- CALLBACK_HOSTNAME string = "127.0.0.1"
29
- CALLBACK_PATH string = "/authorization-code/callback"
30
- TIMEOUT_SECONDS time.Duration = 120 * time .Second
31
- AUTHENTICATED_MESSAGE = "Your account has been authenticated."
27
+ CONFIG_KEY_OAUTH_TOKEN string = "INTERNAL_OAUTH_TOKEN_STORAGE"
28
+ OAUTH_CLIENT_ID string = "b56d4c2e-b9e1-4d27-8773-ad47eafb0956"
29
+ CALLBACK_HOSTNAME string = "127.0.0.1"
30
+ CALLBACK_PATH string = "/authorization-code/callback"
31
+ TIMEOUT_SECONDS time.Duration = 120 * time .Second
32
+ AUTHENTICATED_MESSAGE = "Your account has been authenticated."
33
+ PARAMETER_CLIENT_ID string = "client-id"
34
+ PARAMETER_CLIENT_SECRET string = "client-secret"
35
+ )
36
+
37
+ type GrantType int
38
+
39
+ const (
40
+ ClientCredentialsGrant GrantType = iota
41
+ AuthorizationCodeGrant
32
42
)
33
43
34
44
var _ Authenticator = (* oAuth2Authenticator )(nil )
@@ -42,6 +52,7 @@ type oAuth2Authenticator struct {
42
52
oauthConfig * oauth2.Config
43
53
token * oauth2.Token
44
54
headless bool
55
+ grantType GrantType
45
56
openBrowserFunc func (authUrl string )
46
57
shutdownServerFunc func (server * http.Server )
47
58
tokenRefresherFunc func (ctx context.Context , oauthConfig * oauth2.Config , token * oauth2.Token ) (* oauth2.Token , error )
@@ -89,6 +100,21 @@ func getOAuthConfiguration(config configuration.Configuration) *oauth2.Config {
89
100
AuthURL : authUrl ,
90
101
},
91
102
}
103
+
104
+ if determineGrantType (config ) == ClientCredentialsGrant {
105
+ conf .ClientID = config .GetString (PARAMETER_CLIENT_ID )
106
+ conf .ClientSecret = config .GetString (PARAMETER_CLIENT_SECRET )
107
+ }
108
+
109
+ return conf
110
+ }
111
+
112
+ func getOAuthConfigurationClientCredentials (in * oauth2.Config ) * clientcredentials.Config {
113
+ conf := & clientcredentials.Config {
114
+ ClientID : in .ClientID ,
115
+ ClientSecret : in .ClientSecret ,
116
+ TokenURL : in .Endpoint .TokenURL ,
117
+ }
92
118
return conf
93
119
}
94
120
@@ -138,6 +164,20 @@ func RefreshToken(ctx context.Context, oauthConfig *oauth2.Config, token *oauth2
138
164
return tokenSource .Token ()
139
165
}
140
166
167
+ func refreshTokenClientCredentials (ctx context.Context , oauthConfig * oauth2.Config , token * oauth2.Token ) (* oauth2.Token , error ) {
168
+ conf := getOAuthConfigurationClientCredentials (oauthConfig )
169
+ tokenSource := conf .TokenSource (ctx )
170
+ return tokenSource .Token ()
171
+ }
172
+
173
+ func determineGrantType (config configuration.Configuration ) GrantType {
174
+ grantType := AuthorizationCodeGrant
175
+ if config .IsSet (PARAMETER_CLIENT_SECRET ) && config .IsSet (PARAMETER_CLIENT_ID ) {
176
+ grantType = ClientCredentialsGrant
177
+ }
178
+ return grantType
179
+ }
180
+
141
181
//goland:noinspection GoUnusedExportedFunction
142
182
func NewOAuth2Authenticator (config configuration.Configuration , httpClient * http.Client ) Authenticator {
143
183
return NewOAuth2AuthenticatorWithOpts (config , WithHttpClient (httpClient ))
@@ -154,7 +194,14 @@ func NewOAuth2AuthenticatorWithOpts(config configuration.Configuration, opts ...
154
194
o .httpClient = http .DefaultClient
155
195
o .openBrowserFunc = OpenBrowser
156
196
o .shutdownServerFunc = ShutdownServer
157
- o .tokenRefresherFunc = RefreshToken
197
+ o .grantType = determineGrantType (config )
198
+
199
+ // set refresh function depending on grant type
200
+ if o .grantType == ClientCredentialsGrant {
201
+ o .tokenRefresherFunc = refreshTokenClientCredentials
202
+ } else {
203
+ o .tokenRefresherFunc = RefreshToken
204
+ }
158
205
159
206
// apply options
160
207
for _ , opt := range opts {
@@ -193,6 +240,37 @@ func (o *oAuth2Authenticator) persistToken(token *oauth2.Token) {
193
240
}
194
241
195
242
func (o * oAuth2Authenticator ) Authenticate () error {
243
+ var err error
244
+
245
+ if o .grantType == ClientCredentialsGrant {
246
+ err = o .authenticateWithClientCredentialsGrant ()
247
+ } else {
248
+ err = o .authenticateWithAuthorizationCode ()
249
+ }
250
+
251
+ return err
252
+ }
253
+
254
+ func (o * oAuth2Authenticator ) authenticateWithClientCredentialsGrant () error {
255
+ ctx := context .Background ()
256
+ config := getOAuthConfigurationClientCredentials (o .oauthConfig )
257
+
258
+ // Use the custom HTTP client when requesting a token.
259
+ if o .httpClient != nil {
260
+ ctx = context .WithValue (ctx , oauth2 .HTTPClient , o .httpClient )
261
+ }
262
+
263
+ // get token
264
+ token , err := config .Token (ctx )
265
+ if err != nil {
266
+ return err
267
+ }
268
+
269
+ o .persistToken (token )
270
+ return err
271
+ }
272
+
273
+ func (o * oAuth2Authenticator ) authenticateWithAuthorizationCode () error {
196
274
var responseCode string
197
275
var responseState string
198
276
var responseError string
0 commit comments