1717
1818import static org .assertj .core .api .Assertions .assertThat ;
1919import static org .mockito .ArgumentMatchers .any ;
20+ import static org .mockito .Mockito .mock ;
2021import static org .mockito .Mockito .times ;
2122import static org .mockito .Mockito .verify ;
2223import static org .mockito .Mockito .when ;
2324
24- import java .util .ArrayList ;
2525import java .util .Collections ;
2626import java .util .List ;
27+ import java .util .Map ;
2728import java .util .Optional ;
29+ import java .util .concurrent .CompletableFuture ;
2830import java .util .function .Supplier ;
2931import org .junit .Before ;
3032import org .junit .Test ;
3133import org .junit .runner .RunWith ;
3234import org .mockito .Mock ;
3335import org .mockito .junit .MockitoJUnitRunner ;
3436import software .amazon .awssdk .auth .credentials .AwsBasicCredentials ;
35- import software .amazon .awssdk .auth .credentials .DefaultCredentialsProvider ;
3637import software .amazon .awssdk .auth .credentials .StaticCredentialsProvider ;
3738import software .amazon .awssdk .awscore .AwsRequestOverrideConfiguration ;
3839import software .amazon .awssdk .awscore .client .config .AwsClientOption ;
3940import software .amazon .awssdk .core .SdkRequest ;
4041import software .amazon .awssdk .core .SdkResponse ;
42+ import software .amazon .awssdk .core .SelectedAuthScheme ;
4143import software .amazon .awssdk .core .checksums .ChecksumSpecs ;
4244import software .amazon .awssdk .core .client .config .SdkAdvancedClientOption ;
4345import software .amazon .awssdk .core .client .config .SdkClientConfiguration ;
5153import software .amazon .awssdk .core .interceptor .trait .HttpChecksum ;
5254import software .amazon .awssdk .core .internal .util .HttpChecksumUtils ;
5355import software .amazon .awssdk .core .signer .Signer ;
56+ import software .amazon .awssdk .http .auth .aws .scheme .AwsV4AuthScheme ;
57+ import software .amazon .awssdk .http .auth .scheme .NoAuthAuthScheme ;
58+ import software .amazon .awssdk .http .auth .spi .scheme .AuthScheme ;
59+ import software .amazon .awssdk .http .auth .spi .scheme .AuthSchemeOption ;
60+ import software .amazon .awssdk .http .auth .spi .signer .HttpSigner ;
5461import software .amazon .awssdk .identity .spi .AwsCredentialsIdentity ;
5562import software .amazon .awssdk .identity .spi .IdentityProvider ;
5663import software .amazon .awssdk .identity .spi .IdentityProviders ;
@@ -65,16 +72,25 @@ public class AwsExecutionContextBuilderTest {
6572 @ Mock
6673 ExecutionInterceptor interceptor ;
6774
75+ @ Mock
76+ IdentityProvider <AwsCredentialsIdentity > defaultCredentialsProvider ;
77+
6878 @ Mock
6979 Signer defaultSigner ;
7080
7181 @ Mock
7282 Signer clientOverrideSigner ;
7383
84+ @ Mock
85+ Map <String , AuthScheme <?>> defaultAuthSchemes ;
86+
7487 @ Before
7588 public void setUp () throws Exception {
7689 when (sdkRequest .overrideConfiguration ()).thenReturn (Optional .empty ());
7790 when (interceptor .modifyRequest (any (), any ())).thenReturn (sdkRequest );
91+ when (defaultCredentialsProvider .resolveIdentity ()).thenAnswer (
92+ invocationOnMock -> CompletableFuture .completedFuture (AwsCredentialsIdentity .create ("ak" , "sk" )));
93+
7894 }
7995
8096 @ Test
@@ -109,17 +125,45 @@ public void verifyCoreExecutionAttributesTakePrecedence() {
109125 assertThat (executionContext .executionAttributes ().getAttribute (SdkExecutionAttribute .SERVICE_NAME )).isEqualTo ("DoNotOverrideService" );
110126 }
111127
128+ // pre SRA, AuthorizationStrategy would setup the signer and resolve identity.
112129 @ Test
113- public void signing_ifNoOverrides_assignDefaultSigner () {
130+ public void preSra_signing_ifNoOverrides_assignDefaultSigner_resolveIdentity () {
114131 ExecutionContext executionContext =
115132 AwsExecutionContextBuilder .invokeInterceptorsAndCreateExecutionContext (clientExecutionParams (),
116- testClientConfiguration ().build ());
133+ preSraClientConfiguration ().build ());
117134
118135 assertThat (executionContext .signer ()).isEqualTo (defaultSigner );
136+ verify (defaultCredentialsProvider , times (1 )).resolveIdentity ();
119137 }
120138
139+ // This is post SRA case. This is asserting that AuthorizationStrategy is not used.
121140 @ Test
122- public void signing_ifClientOverride_assignClientOverrideSigner () {
141+ public void postSra_ifNoOverrides_doesNotResolveIdentity_doesNotAssignSigner () {
142+ ExecutionContext executionContext =
143+ AwsExecutionContextBuilder .invokeInterceptorsAndCreateExecutionContext (clientExecutionParams (),
144+ testClientConfiguration ().build ());
145+
146+ assertThat (executionContext .signer ()).isNull ();
147+ verify (defaultCredentialsProvider , times (0 )).resolveIdentity ();
148+ }
149+
150+ @ Test
151+ public void preSra_signing_ifClientOverride_assignClientOverrideSigner_resolveIdentity () {
152+ Optional overrideConfiguration = Optional .of (AwsRequestOverrideConfiguration .builder ()
153+ .signer (clientOverrideSigner )
154+ .build ());
155+ when (sdkRequest .overrideConfiguration ()).thenReturn (overrideConfiguration );
156+
157+ ExecutionContext executionContext =
158+ AwsExecutionContextBuilder .invokeInterceptorsAndCreateExecutionContext (clientExecutionParams (),
159+ preSraClientConfiguration ().build ());
160+
161+ assertThat (executionContext .signer ()).isEqualTo (clientOverrideSigner );
162+ verify (defaultCredentialsProvider , times (1 )).resolveIdentity ();
163+ }
164+
165+ @ Test
166+ public void postSra_signing_ifClientOverride_assignClientOverrideSigner_resolveIdentity () {
123167 Optional overrideConfiguration = Optional .of (AwsRequestOverrideConfiguration .builder ()
124168 .signer (clientOverrideSigner )
125169 .build ());
@@ -130,6 +174,102 @@ public void signing_ifClientOverride_assignClientOverrideSigner() {
130174 testClientConfiguration ().build ());
131175
132176 assertThat (executionContext .signer ()).isEqualTo (clientOverrideSigner );
177+ verify (defaultCredentialsProvider , times (1 )).resolveIdentity ();
178+ }
179+
180+ @ Test
181+ public void preSra_authTypeNone_doesNotAssignSigner_doesNotResolveIdentity () {
182+ SdkClientConfiguration .Builder clientConfig = preSraClientConfiguration ();
183+ clientConfig .option (SdkClientOption .EXECUTION_ATTRIBUTES )
184+ // yes, our code would put false instead of true
185+ .putAttribute (SdkInternalExecutionAttribute .IS_NONE_AUTH_TYPE_REQUEST , false );
186+
187+ ExecutionContext executionContext =
188+ AwsExecutionContextBuilder .invokeInterceptorsAndCreateExecutionContext (clientExecutionParams (),
189+ clientConfig .build ());
190+
191+ assertThat (executionContext .signer ()).isNull ();
192+ verify (defaultCredentialsProvider , times (0 )).resolveIdentity ();
193+ }
194+
195+ @ Test
196+ public void postSra_authTypeNone_doesNotAssignSigner_doesNotResolveIdentity () {
197+ SdkClientConfiguration .Builder clientConfig = noAuthAuthSchemeClientConfiguration ();
198+
199+ ExecutionContext executionContext =
200+ AwsExecutionContextBuilder .invokeInterceptorsAndCreateExecutionContext (clientExecutionParams (),
201+ clientConfig .build ());
202+
203+ assertThat (executionContext .signer ()).isNull ();
204+ verify (defaultCredentialsProvider , times (0 )).resolveIdentity ();
205+ }
206+
207+ @ Test
208+ public void preSra_authTypeNone_signerClientOverride_doesNotAssignSigner_doesNotResolveIdentity () {
209+ SdkClientConfiguration .Builder clientConfig = preSraClientConfiguration ();
210+ clientConfig .option (SdkClientOption .EXECUTION_ATTRIBUTES )
211+ // yes, our code would put false instead of true
212+ .putAttribute (SdkInternalExecutionAttribute .IS_NONE_AUTH_TYPE_REQUEST , false );
213+ clientConfig .option (SdkAdvancedClientOption .SIGNER , this .clientOverrideSigner )
214+ .option (SdkClientOption .SIGNER_OVERRIDDEN , true );
215+
216+ ExecutionContext executionContext =
217+ AwsExecutionContextBuilder .invokeInterceptorsAndCreateExecutionContext (clientExecutionParams (),
218+ clientConfig .build ());
219+
220+ assertThat (executionContext .signer ()).isNull ();
221+ verify (defaultCredentialsProvider , times (0 )).resolveIdentity ();
222+ }
223+
224+ @ Test
225+ public void postSra_authTypeNone_signerClientOverride_doesNotAssignSigner_doesNotResolveIdentity () {
226+ SdkClientConfiguration .Builder clientConfig = noAuthAuthSchemeClientConfiguration ();
227+ clientConfig .option (SdkAdvancedClientOption .SIGNER , this .clientOverrideSigner )
228+ .option (SdkClientOption .SIGNER_OVERRIDDEN , true );
229+
230+ ExecutionContext executionContext =
231+ AwsExecutionContextBuilder .invokeInterceptorsAndCreateExecutionContext (clientExecutionParams (),
232+ clientConfig .build ());
233+
234+ assertThat (executionContext .signer ()).isNull ();
235+ verify (defaultCredentialsProvider , times (0 )).resolveIdentity ();
236+ }
237+
238+ @ Test
239+ public void preSra_authTypeNone_signerRequestOverride_doesNotAssignSigner_doesNotResolveIdentity () {
240+ SdkClientConfiguration .Builder clientConfig = preSraClientConfiguration ();
241+ clientConfig .option (SdkClientOption .EXECUTION_ATTRIBUTES )
242+ // yes, our code would put false instead of true
243+ .putAttribute (SdkInternalExecutionAttribute .IS_NONE_AUTH_TYPE_REQUEST , false );
244+
245+ Optional overrideConfiguration = Optional .of (AwsRequestOverrideConfiguration .builder ()
246+ .signer (clientOverrideSigner )
247+ .build ());
248+ when (sdkRequest .overrideConfiguration ()).thenReturn (overrideConfiguration );
249+
250+ ExecutionContext executionContext =
251+ AwsExecutionContextBuilder .invokeInterceptorsAndCreateExecutionContext (clientExecutionParams (),
252+ clientConfig .build ());
253+
254+ assertThat (executionContext .signer ()).isNull ();
255+ verify (defaultCredentialsProvider , times (0 )).resolveIdentity ();
256+ }
257+
258+ @ Test
259+ public void postSra_authTypeNone_signerRequestOverride_doesNotAssignSigner_doesNotResolveIdentity () {
260+ SdkClientConfiguration .Builder clientConfig = noAuthAuthSchemeClientConfiguration ();
261+
262+ Optional overrideConfiguration = Optional .of (AwsRequestOverrideConfiguration .builder ()
263+ .signer (clientOverrideSigner )
264+ .build ());
265+ when (sdkRequest .overrideConfiguration ()).thenReturn (overrideConfiguration );
266+
267+ ExecutionContext executionContext =
268+ AwsExecutionContextBuilder .invokeInterceptorsAndCreateExecutionContext (clientExecutionParams (),
269+ clientConfig .build ());
270+
271+ assertThat (executionContext .signer ()).isNull ();
272+ verify (defaultCredentialsProvider , times (0 )).resolveIdentity ();
133273 }
134274
135275 @ Test
@@ -255,11 +395,44 @@ private ClientExecutionParams<SdkRequest, SdkResponse> clientExecutionParams() {
255395 }
256396
257397 private SdkClientConfiguration .Builder testClientConfiguration () {
398+ // In real SRA case, SelectedAuthScheme is setup as an executionAttribute by {Service}AuthSchemeInterceptor that is setup
399+ // in EXECUTION_INTERCEPTORS. But, faking it here for unit test, by already setting SELECTED_AUTH_SCHEME into the
400+ // executionAttributes.
401+ SelectedAuthScheme <?> selectedAuthScheme = new SelectedAuthScheme <>(
402+ CompletableFuture .completedFuture (AwsCredentialsIdentity .create ("ak" , "sk" )),
403+ mock (HttpSigner .class ),
404+ AuthSchemeOption .builder ().schemeId (AwsV4AuthScheme .SCHEME_ID ).build ()
405+ );
406+ ExecutionAttributes executionAttributes =
407+ ExecutionAttributes .builder ()
408+ .put (SdkInternalExecutionAttribute .SELECTED_AUTH_SCHEME , selectedAuthScheme )
409+ .build ();
410+
258411 List <ExecutionInterceptor > interceptorList = Collections .singletonList (interceptor );
259412 return SdkClientConfiguration .builder ()
260- .option (SdkClientOption .EXECUTION_INTERCEPTORS , new ArrayList <>())
261413 .option (SdkClientOption .EXECUTION_INTERCEPTORS , interceptorList )
262- .option (AwsClientOption .CREDENTIALS_IDENTITY_PROVIDER , DefaultCredentialsProvider .create ())
263- .option (SdkAdvancedClientOption .SIGNER , this .defaultSigner );
414+ .option (AwsClientOption .CREDENTIALS_IDENTITY_PROVIDER , defaultCredentialsProvider )
415+ .option (SdkClientOption .AUTH_SCHEMES , defaultAuthSchemes )
416+ .option (SdkClientOption .EXECUTION_ATTRIBUTES , executionAttributes );
417+ }
418+
419+ private SdkClientConfiguration .Builder noAuthAuthSchemeClientConfiguration () {
420+ SdkClientConfiguration .Builder clientConfig = testClientConfiguration ();
421+ SelectedAuthScheme <?> selectedNoAuthScheme = new SelectedAuthScheme <>(
422+ CompletableFuture .completedFuture (AwsCredentialsIdentity .create ("ak" , "sk" )),
423+ mock (HttpSigner .class ),
424+ AuthSchemeOption .builder ().schemeId (NoAuthAuthScheme .SCHEME_ID ).build ()
425+ );
426+ clientConfig .option (SdkClientOption .EXECUTION_ATTRIBUTES )
427+ .putAttribute (SdkInternalExecutionAttribute .SELECTED_AUTH_SCHEME , selectedNoAuthScheme );
428+ return clientConfig ;
429+ }
430+
431+ private SdkClientConfiguration .Builder preSraClientConfiguration () {
432+ SdkClientConfiguration .Builder clientConfiguration = testClientConfiguration ();
433+ clientConfiguration .option (SdkClientOption .EXECUTION_ATTRIBUTES )
434+ .putAttribute (SdkInternalExecutionAttribute .SELECTED_AUTH_SCHEME , null );
435+ return clientConfiguration .option (SdkClientOption .AUTH_SCHEMES , null )
436+ .option (SdkAdvancedClientOption .SIGNER , this .defaultSigner );
264437 }
265438}
0 commit comments