@@ -21,6 +21,14 @@ jest.mock("@aws-sdk/shared-ini-file-loader", () => ({
2121} ) ) ;
2222import { loadSharedConfigFiles } from "@aws-sdk/shared-ini-file-loader" ;
2323
24+ jest . mock ( "@aws-sdk/credential-provider-sso" , ( ) => {
25+ const ssoProvider = jest . fn ( ) ;
26+ return {
27+ fromSSO : jest . fn ( ) . mockReturnValue ( ssoProvider ) ,
28+ } ;
29+ } ) ;
30+ import { fromSSO , FromSSOInit } from "@aws-sdk/credential-provider-sso" ;
31+
2432jest . mock ( "@aws-sdk/credential-provider-ini" , ( ) => {
2533 const iniProvider = jest . fn ( ) ;
2634 return {
@@ -81,11 +89,13 @@ beforeEach(() => {
8189 } ) ;
8290
8391 ( fromEnv ( ) as any ) . mockClear ( ) ;
92+ ( fromSSO ( ) as any ) . mockClear ( ) ;
8493 ( fromIni ( ) as any ) . mockClear ( ) ;
8594 ( fromProcess ( ) as any ) . mockClear ( ) ;
8695 ( fromContainerMetadata ( ) as any ) . mockClear ( ) ;
8796 ( fromInstanceMetadata ( ) as any ) . mockClear ( ) ;
8897 ( fromEnv as any ) . mockClear ( ) ;
98+ ( fromSSO as any ) . mockClear ( ) ;
8999 ( fromIni as any ) . mockClear ( ) ;
90100 ( fromProcess as any ) . mockClear ( ) ;
91101 ( fromContainerMetadata as any ) . mockClear ( ) ;
@@ -120,17 +130,37 @@ describe("defaultProvider", () => {
120130 expect ( ( fromInstanceMetadata ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
121131 } ) ;
122132
133+ it ( "should stop after the SSO provider if credentials have been found" , async ( ) => {
134+ const creds = {
135+ accessKeyId : "foo" ,
136+ secretAccessKey : "bar" ,
137+ } ;
138+
139+ ( fromEnv ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Nothing here!" ) ) ) ;
140+ ( fromSSO ( ) as any ) . mockImplementation ( ( ) => Promise . resolve ( creds ) ) ;
141+
142+ expect ( await defaultProvider ( ) ( ) ) . toEqual ( creds ) ;
143+ expect ( ( fromEnv ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
144+ expect ( ( fromSSO ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
145+ expect ( ( fromIni ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
146+ expect ( ( fromProcess ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
147+ expect ( ( fromContainerMetadata ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
148+ expect ( ( fromInstanceMetadata ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
149+ } ) ;
150+
123151 it ( "should stop after the ini provider if credentials have been found" , async ( ) => {
124152 const creds = {
125153 accessKeyId : "foo" ,
126154 secretAccessKey : "bar" ,
127155 } ;
128156
129157 ( fromEnv ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Nothing here!" ) ) ) ;
158+ ( fromSSO ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Nothing here!" ) ) ) ;
130159 ( fromIni ( ) as any ) . mockImplementation ( ( ) => Promise . resolve ( creds ) ) ;
131160
132161 expect ( await defaultProvider ( ) ( ) ) . toEqual ( creds ) ;
133162 expect ( ( fromEnv ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
163+ expect ( ( fromSSO ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
134164 expect ( ( fromIni ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
135165 expect ( ( fromProcess ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
136166 expect ( ( fromContainerMetadata ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
@@ -144,11 +174,13 @@ describe("defaultProvider", () => {
144174 } ;
145175
146176 ( fromEnv ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Nothing here!" ) ) ) ;
177+ ( fromSSO ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Nothing here!" ) ) ) ;
147178 ( fromIni ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Nothing here!" ) ) ) ;
148179 ( fromProcess ( ) as any ) . mockImplementation ( ( ) => Promise . resolve ( creds ) ) ;
149180
150181 expect ( await defaultProvider ( ) ( ) ) . toEqual ( creds ) ;
151182 expect ( ( fromEnv ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
183+ expect ( ( fromSSO ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
152184 expect ( ( fromIni ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
153185 expect ( ( fromProcess ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
154186 expect ( ( fromContainerMetadata ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
@@ -161,12 +193,14 @@ describe("defaultProvider", () => {
161193 secretAccessKey : "bar" ,
162194 } ;
163195 ( fromEnv ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Keep moving!" ) ) ) ;
196+ ( fromSSO ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Nope!" ) ) ) ;
164197 ( fromIni ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Nothing here!" ) ) ) ;
165198 ( fromProcess ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Nor here!" ) ) ) ;
166199 ( fromInstanceMetadata ( ) as any ) . mockImplementation ( ( ) => Promise . resolve ( creds ) ) ;
167200
168201 expect ( await defaultProvider ( ) ( ) ) . toEqual ( creds ) ;
169202 expect ( ( fromEnv ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
203+ expect ( ( fromSSO ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
170204 expect ( ( fromIni ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
171205 expect ( ( fromProcess ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
172206 expect ( ( fromContainerMetadata ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
@@ -180,6 +214,7 @@ describe("defaultProvider", () => {
180214 } ;
181215
182216 ( fromEnv ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Keep moving!" ) ) ) ;
217+ ( fromSSO ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Nope!" ) ) ) ;
183218 ( fromIni ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Nothing here!" ) ) ) ;
184219 ( fromProcess ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Nor here!" ) ) ) ;
185220 ( fromInstanceMetadata ( ) as any ) . mockImplementation ( ( ) => Promise . resolve ( creds ) ) ;
@@ -198,6 +233,7 @@ describe("defaultProvider", () => {
198233 } ;
199234
200235 ( fromEnv ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Keep moving!" ) ) ) ;
236+ ( fromSSO ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Nope!" ) ) ) ;
201237 ( fromIni ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Nothing here!" ) ) ) ;
202238 ( fromProcess ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Nor here!" ) ) ) ;
203239 ( fromInstanceMetadata ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new Error ( "PANIC" ) ) ) ;
@@ -207,6 +243,7 @@ describe("defaultProvider", () => {
207243
208244 expect ( await defaultProvider ( ) ( ) ) . toEqual ( creds ) ;
209245 expect ( ( fromEnv ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
246+ expect ( ( fromSSO ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
210247 expect ( ( fromIni ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
211248 expect ( ( fromProcess ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
212249 expect ( ( fromContainerMetadata ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
@@ -220,16 +257,41 @@ describe("defaultProvider", () => {
220257 } ;
221258
222259 ( fromEnv ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Keep moving!" ) ) ) ;
260+ ( fromSSO ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Nope!" ) ) ) ;
223261 ( fromIni ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Nothing here!" ) ) ) ;
224262 ( fromProcess ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Nor here!" ) ) ) ;
225263 ( fromInstanceMetadata ( ) as any ) . mockImplementation ( ( ) => Promise . resolve ( creds ) ) ;
226264
227265 await expect ( defaultProvider ( ) ( ) ) . resolves ;
228266 expect ( ( loadSharedConfigFiles as any ) . mock . calls . length ) . toBe ( 1 ) ;
229267 expect ( ( fromIni as any ) . mock . calls [ 1 ] [ 0 ] ) . toMatchObject ( { loadedConfig : loadSharedConfigFiles ( ) } ) ;
268+ expect ( ( fromSSO as any ) . mock . calls [ 1 ] [ 0 ] ) . toMatchObject ( { loadedConfig : loadSharedConfigFiles ( ) } ) ;
230269 expect ( ( fromProcess as any ) . mock . calls [ 1 ] [ 0 ] ) . toMatchObject ( { loadedConfig : loadSharedConfigFiles ( ) } ) ;
231270 } ) ;
232271
272+ it ( "should pass configuration on to the SSO provider" , async ( ) => {
273+ const ssoConfig : FromSSOInit = {
274+ profile : "foo" ,
275+ filepath : "/home/user/.secrets/credentials.ini" ,
276+ configFilepath : "/home/user/.secrets/credentials.ini" ,
277+ } ;
278+
279+ ( fromEnv ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Keep moving!" ) ) ) ;
280+ ( fromSSO ( ) as any ) . mockImplementation ( ( ) =>
281+ Promise . resolve ( {
282+ accessKeyId : "foo" ,
283+ secretAccessKey : "bar" ,
284+ } )
285+ ) ;
286+
287+ ( fromSSO as any ) . mockClear ( ) ;
288+
289+ await expect ( defaultProvider ( ssoConfig ) ( ) ) . resolves ;
290+
291+ expect ( ( fromSSO as any ) . mock . calls . length ) . toBe ( 1 ) ;
292+ expect ( ( fromSSO as any ) . mock . calls [ 0 ] [ 0 ] ) . toEqual ( { ...ssoConfig , loadedConfig } ) ;
293+ } ) ;
294+
233295 it ( "should pass configuration on to the ini provider" , async ( ) => {
234296 const iniConfig : FromIniInit = {
235297 profile : "foo" ,
@@ -387,60 +449,86 @@ describe("defaultProvider", () => {
387449
388450 // CF https://github.com/boto/botocore/blob/1.8.32/botocore/credentials.py#L104
389451 describe ( "explicit profiles" , ( ) => {
390- it ( "should only consult the ini provider if a profile has been specified " , async ( ) => {
452+ it ( "should only consult SSO provider if profile has been set " , async ( ) => {
391453 const creds = {
392454 accessKeyId : "foo" ,
393455 secretAccessKey : "bar" ,
394456 } ;
395457
396- ( fromEnv ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new Error ( "PANIC" ) ) ) ;
397- ( fromIni ( ) as any ) . mockImplementation ( ( ) => Promise . resolve ( creds ) ) ;
398- ( fromInstanceMetadata ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new Error ( "PANIC" ) ) ) ;
399- ( fromContainerMetadata ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new Error ( "PANIC" ) ) ) ;
458+ ( fromEnv ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "PANIC" ) ) ) ;
459+ ( fromSSO ( ) as any ) . mockImplementation ( ( ) => Promise . resolve ( Promise . resolve ( creds ) ) ) ;
460+ ( fromIni ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "PANIC" ) ) ) ;
461+ ( fromInstanceMetadata ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "PANIC" ) ) ) ;
462+ ( fromContainerMetadata ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "PANIC" ) ) ) ;
400463
401464 expect ( await defaultProvider ( { profile : "foo" } ) ( ) ) . toEqual ( creds ) ;
402465 expect ( ( fromEnv ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
403- expect ( ( fromIni ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
466+ expect ( ( fromSSO ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
467+ expect ( ( fromIni ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
404468 expect ( ( fromContainerMetadata ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
405469 expect ( ( fromInstanceMetadata ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
406470 } ) ;
407471
408- it ( "should only consult the ini provider if the profile environment variable has been set" , async ( ) => {
472+ it ( "should only consult SSO provider if the profile environment variable has been set" , async ( ) => {
409473 const creds = {
410474 accessKeyId : "foo" ,
411475 secretAccessKey : "bar" ,
412476 } ;
413477
414- ( fromEnv ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new Error ( "PANIC" ) ) ) ;
415- ( fromIni ( ) as any ) . mockImplementation ( ( ) => Promise . resolve ( creds ) ) ;
416- ( fromProcess ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new Error ( "PANIC" ) ) ) ;
417- ( fromInstanceMetadata ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new Error ( "PANIC" ) ) ) ;
418- ( fromContainerMetadata ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new Error ( "PANIC" ) ) ) ;
478+ ( fromEnv ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "PANIC" ) ) ) ;
479+ ( fromSSO ( ) as any ) . mockImplementation ( ( ) => Promise . resolve ( creds ) ) ;
480+ ( fromIni ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "PANIC" ) ) ) ;
481+ ( fromProcess ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "PANIC" ) ) ) ;
482+ ( fromInstanceMetadata ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "PANIC" ) ) ) ;
483+ ( fromContainerMetadata ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "PANIC" ) ) ) ;
419484
420485 process . env [ ENV_PROFILE ] = "foo" ;
421486 expect ( await defaultProvider ( ) ( ) ) . toEqual ( creds ) ;
422487 expect ( ( fromEnv ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
423- expect ( ( fromIni ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
488+ expect ( ( fromSSO ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
489+ expect ( ( fromIni ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
424490 expect ( ( fromProcess ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
425491 expect ( ( fromContainerMetadata ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
426492 expect ( ( fromInstanceMetadata ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
427493 } ) ;
428494
495+ it ( "should consult ini provider if no credentials is not found in SSO provider" , async ( ) => {
496+ const creds = {
497+ accessKeyId : "foo" ,
498+ secretAccessKey : "bar" ,
499+ } ;
500+
501+ ( fromEnv ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "PANIC" ) ) ) ;
502+ ( fromSSO ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "PANIC" ) ) ) ;
503+ ( fromIni ( ) as any ) . mockImplementation ( ( ) => Promise . resolve ( Promise . resolve ( creds ) ) ) ;
504+ ( fromInstanceMetadata ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "PANIC" ) ) ) ;
505+ ( fromContainerMetadata ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "PANIC" ) ) ) ;
506+
507+ expect ( await defaultProvider ( { profile : "foo" } ) ( ) ) . toEqual ( creds ) ;
508+ expect ( ( fromEnv ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
509+ expect ( ( fromSSO ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
510+ expect ( ( fromIni ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
511+ expect ( ( fromContainerMetadata ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
512+ expect ( ( fromInstanceMetadata ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
513+ } ) ;
514+
429515 it ( "should consult the process provider if no credentials are found in the ini provider" , async ( ) => {
430516 const creds = {
431517 accessKeyId : "foo" ,
432518 secretAccessKey : "bar" ,
433519 } ;
434520
435- ( fromEnv ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new Error ( "PANIC" ) ) ) ;
436- ( fromIni ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "Nothing here!" ) ) ) ;
521+ ( fromEnv ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "PANIC" ) ) ) ;
522+ ( fromSSO ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "PANIC" ) ) ) ;
523+ ( fromIni ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "PANIC" ) ) ) ;
437524 ( fromProcess ( ) as any ) . mockImplementation ( ( ) => Promise . resolve ( creds ) ) ;
438- ( fromInstanceMetadata ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new Error ( "PANIC" ) ) ) ;
439- ( fromContainerMetadata ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new Error ( "PANIC" ) ) ) ;
525+ ( fromInstanceMetadata ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "PANIC" ) ) ) ;
526+ ( fromContainerMetadata ( ) as any ) . mockImplementation ( ( ) => Promise . reject ( new ProviderError ( "PANIC" ) ) ) ;
440527
441528 process . env [ ENV_PROFILE ] = "foo" ;
442529 expect ( await defaultProvider ( ) ( ) ) . toEqual ( creds ) ;
443530 expect ( ( fromEnv ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
531+ expect ( ( fromSSO ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
444532 expect ( ( fromIni ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
445533 expect ( ( fromProcess ( ) as any ) . mock . calls . length ) . toBe ( 1 ) ;
446534 expect ( ( fromContainerMetadata ( ) as any ) . mock . calls . length ) . toBe ( 0 ) ;
0 commit comments