2020import static org .junit .jupiter .api .Assertions .assertNotNull ;
2121import static org .junit .jupiter .api .Assertions .assertThrows ;
2222import static org .junit .jupiter .api .Assertions .assertTrue ;
23- import static org .mockito .ArgumentMatchers .any ;
24- import static org .mockito .Mockito .mock ;
25- import static org .mockito .Mockito .never ;
26- import static org .mockito .Mockito .times ;
27- import static org .mockito .Mockito .verify ;
28- import static org .mockito .Mockito .when ;
23+
2924import static software .amazon .awssdk .services .signin .auth .internal .DpopTestUtils .VALID_TEST_PEM ;
3025import static software .amazon .awssdk .services .signin .auth .internal .DpopTestUtils .getJwtPayloadFromEncodedDpopHeader ;
3126import static software .amazon .awssdk .services .signin .auth .internal .DpopTestUtils .verifySignature ;
4136import org .junit .jupiter .api .BeforeEach ;
4237import org .junit .jupiter .api .Test ;
4338import org .junit .jupiter .api .io .TempDir ;
44- import org .mockito .ArgumentCaptor ;
4539import software .amazon .awssdk .auth .credentials .AwsCredentials ;
4640import software .amazon .awssdk .auth .credentials .AwsSessionCredentials ;
47- import software .amazon .awssdk .auth .signer .AwsSignerExecutionAttribute ;
4841import software .amazon .awssdk .core .SdkRequest ;
4942import software .amazon .awssdk .core .exception .SdkClientException ;
5043import software .amazon .awssdk .core .interceptor .Context ;
6154import software .amazon .awssdk .services .signin .internal .LoginAccessToken ;
6255import software .amazon .awssdk .services .signin .internal .OnDiskTokenManager ;
6356import software .amazon .awssdk .services .signin .model .CreateOAuth2TokenRequest ;
64- import software .amazon .awssdk .services .signin .model .CreateOAuth2TokenResponse ;
57+ import software .amazon .awssdk .services .signin .model .OAuth2ErrorCode ;
6558import software .amazon .awssdk .services .signin .model .SigninException ;
66- import software .amazon .awssdk .testutils .service .http .MockAsyncHttpClient ;
6759import software .amazon .awssdk .testutils .service .http .MockSyncHttpClient ;
60+ import software .amazon .awssdk .utils .StringInputStream ;
6861
6962public class LoginCredentialsProviderTest {
7063 private static final String LOGIN_SESSION_ID = "loginSessionId" ;
@@ -188,7 +181,7 @@ public void resolveCredentials_whenCredentialsExpired_refreshesAndUpdatesCache()
188181 }
189182
190183 @ Test
191- public void resolveCredentials_whenCredentialsExpired_serviceCallFails_raisesException () {
184+ public void resolveCredentials_whenCredentialsExpired_serviceCallFailsWithGeneric500_raisesException () {
192185 // expired
193186 AwsSessionCredentials creds = buildCredentials (Instant .now ().minusSeconds (60 ));
194187 LoginAccessToken token = buildAccessToken (creds );
@@ -199,7 +192,43 @@ public void resolveCredentials_whenCredentialsExpired_serviceCallFails_raisesExc
199192 .response (SdkHttpResponse .builder ().statusCode (500 ).build ())
200193 .build ()
201194 );
202- assertThrows (SdkClientException .class , () -> loginCredentialsProvider .resolveCredentials ());
195+ assertThrows (SigninException .class , () -> loginCredentialsProvider .resolveCredentials ());
196+ }
197+
198+ @ Test
199+ public void resolveCredentials_whenCredentialsExpired_serviceCallFailsWithTokenExpired_raisesException () {
200+ // expired
201+ AwsSessionCredentials creds = buildCredentials (Instant .now ().minusSeconds (60 ));
202+ LoginAccessToken token = buildAccessToken (creds );
203+ tokenManager .storeToken (token );
204+
205+ stubAccessDeniedException (OAuth2ErrorCode .TOKEN_EXPIRED );
206+ SdkClientException e = assertThrows (SdkClientException .class , () -> loginCredentialsProvider .resolveCredentials ());
207+ assertTrue (e .getMessage ().contains ("Your session has expired" ));
208+ }
209+
210+ @ Test
211+ public void resolveCredentials_whenCredentialsExpired_serviceCallFailsWithUserExpired_raisesException () {
212+ // expired
213+ AwsSessionCredentials creds = buildCredentials (Instant .now ().minusSeconds (60 ));
214+ LoginAccessToken token = buildAccessToken (creds );
215+ tokenManager .storeToken (token );
216+
217+ stubAccessDeniedException (OAuth2ErrorCode .USER_CREDENTIALS_CHANGED );
218+ SdkClientException e = assertThrows (SdkClientException .class , () -> loginCredentialsProvider .resolveCredentials ());
219+ assertTrue (e .getMessage ().contains ("change in your password" ));
220+ }
221+
222+ @ Test
223+ public void resolveCredentials_whenCredentialsExpired_serviceCallFailsWithInsufficentPermissions_raisesException () {
224+ // expired
225+ AwsSessionCredentials creds = buildCredentials (Instant .now ().minusSeconds (60 ));
226+ LoginAccessToken token = buildAccessToken (creds );
227+ tokenManager .storeToken (token );
228+
229+ stubAccessDeniedException (OAuth2ErrorCode .INSUFFICIENT_PERMISSIONS );
230+ SdkClientException e = assertThrows (SdkClientException .class , () -> loginCredentialsProvider .resolveCredentials ());
231+ assertTrue (e .getMessage ().contains ("insufficient permissions" ));
203232 }
204233
205234 private static void verifyResolvedCredentialsAreUpdated (AwsCredentials resolvedCredentials ) {
@@ -254,6 +283,22 @@ private void stubSuccessfulRefreshResponse() {
254283 );
255284 }
256285
286+ private void stubAccessDeniedException (OAuth2ErrorCode errorCode ) {
287+ String errorBody = "{\" error\" :\" " + errorCode + "\" ,\" message\" :\" The refresh token has expired.\" }" ;
288+ mockHttpClient .stubNextResponse (
289+ HttpExecuteResponse
290+ .builder ()
291+ .response (
292+ SdkHttpResponse
293+ .builder ()
294+ .putHeader ("X-Amzn-Errortype" , "AccessDeniedException" )
295+ .statusCode (401 )
296+ .build ())
297+ .responseBody (AbortableInputStream .create (new StringInputStream (errorBody )))
298+ .build ()
299+ );
300+ }
301+
257302 private AwsSessionCredentials buildCredentials (Instant expirationTime ) {
258303 return AwsSessionCredentials .builder ()
259304 .accessKeyId ("akid" )
0 commit comments