Skip to content

Commit

Permalink
Merge pull request #325 from auth0/patch-sec-cm
Browse files Browse the repository at this point in the history
Patch Key alias migration for Secure Credentials Manager
  • Loading branch information
lbalmaceda committed Aug 4, 2020
2 parents 4134c71 + 05cdbbf commit bad61f1
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ public class SecureCredentialsManager {
private static final String KEY_CREDENTIALS = "com.auth0.credentials";
private static final String KEY_EXPIRES_AT = "com.auth0.credentials_expires_at";
private static final String KEY_CAN_REFRESH = "com.auth0.credentials_can_refresh";
private static final String KEY_ALIAS = "com.auth0.key";
private static final String KEY_CRYPTO_ALIAS = "com.auth0.manager_key_alias";
@VisibleForTesting
static final String KEY_ALIAS = "com.auth0.key";

private final AuthenticationAPIClient apiClient;
private final Storage storage;
Expand Down Expand Up @@ -165,6 +167,7 @@ public void saveCredentials(@NonNull Credentials credentials) throws Credentials
storage.store(KEY_CREDENTIALS, encryptedEncoded);
storage.store(KEY_EXPIRES_AT, expiresAt);
storage.store(KEY_CAN_REFRESH, canRefresh);
storage.store(KEY_CRYPTO_ALIAS, KEY_ALIAS);
} catch (IncompatibleDeviceException e) {
throw new CredentialsManagerException(String.format("This device is not compatible with the %s class.", SecureCredentialsManager.class.getSimpleName()), e);
} catch (CryptoException e) {
Expand Down Expand Up @@ -211,6 +214,7 @@ public void clearCredentials() {
storage.remove(KEY_CREDENTIALS);
storage.remove(KEY_EXPIRES_AT);
storage.remove(KEY_CAN_REFRESH);
storage.remove(KEY_CRYPTO_ALIAS);
Log.d(TAG, "Credentials were just removed from the storage");
}

Expand All @@ -223,9 +227,10 @@ public boolean hasValidCredentials() {
String encryptedEncoded = storage.retrieveString(KEY_CREDENTIALS);
Long expiresAt = storage.retrieveLong(KEY_EXPIRES_AT);
Boolean canRefresh = storage.retrieveBoolean(KEY_CAN_REFRESH);
return !(isEmpty(encryptedEncoded) ||
expiresAt == null ||
expiresAt <= getCurrentTimeInMillis() && (canRefresh == null || !canRefresh));
String keyAliasUsed = storage.retrieveString(KEY_CRYPTO_ALIAS);
return KEY_ALIAS.equals(keyAliasUsed) &&
!(isEmpty(encryptedEncoded) || expiresAt == null ||
expiresAt <= getCurrentTimeInMillis() && (canRefresh == null || !canRefresh));
}

private void continueGetCredentials(final BaseCallback<Credentials, CredentialsManagerException> callback) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ public void shouldSaveRefreshableCredentialsInStorage() {
verify(storage).store(eq("com.auth0.credentials"), stringCaptor.capture());
verify(storage).store("com.auth0.credentials_expires_at", sharedExpirationTime);
verify(storage).store("com.auth0.credentials_can_refresh", true);
verify(storage).store("com.auth0.manager_key_alias", SecureCredentialsManager.KEY_ALIAS);
verifyNoMoreInteractions(storage);
final String encodedJson = stringCaptor.getValue();
assertThat(encodedJson, is(notNullValue()));
Expand Down Expand Up @@ -155,6 +156,7 @@ public void shouldSaveRefreshableCredentialsUsingAccessTokenExpForCacheExpiratio
verify(storage).store(eq("com.auth0.credentials"), stringCaptor.capture());
verify(storage).store("com.auth0.credentials_expires_at", accessTokenExpirationTime);
verify(storage).store("com.auth0.credentials_can_refresh", true);
verify(storage).store("com.auth0.manager_key_alias", SecureCredentialsManager.KEY_ALIAS);
verifyNoMoreInteractions(storage);
final String encodedJson = stringCaptor.getValue();
assertThat(encodedJson, is(notNullValue()));
Expand Down Expand Up @@ -183,6 +185,7 @@ public void shouldSaveRefreshableCredentialsUsingIdTokenExpForCacheExpirationInS
verify(storage).store(eq("com.auth0.credentials"), stringCaptor.capture());
verify(storage).store("com.auth0.credentials_expires_at", idTokenExpirationTime);
verify(storage).store("com.auth0.credentials_can_refresh", true);
verify(storage).store("com.auth0.manager_key_alias", SecureCredentialsManager.KEY_ALIAS);
verifyNoMoreInteractions(storage);
final String encodedJson = stringCaptor.getValue();
assertThat(encodedJson, is(notNullValue()));
Expand Down Expand Up @@ -210,6 +213,7 @@ public void shouldSaveNonRefreshableCredentialsInStorage() {
verify(storage).store(eq("com.auth0.credentials"), stringCaptor.capture());
verify(storage).store("com.auth0.credentials_expires_at", expirationTime);
verify(storage).store("com.auth0.credentials_can_refresh", false);
verify(storage).store("com.auth0.manager_key_alias", SecureCredentialsManager.KEY_ALIAS);
verifyNoMoreInteractions(storage);
final String encodedJson = stringCaptor.getValue();
assertThat(encodedJson, is(notNullValue()));
Expand Down Expand Up @@ -573,6 +577,7 @@ public void shouldClearCredentials() {
verify(storage).remove("com.auth0.credentials");
verify(storage).remove("com.auth0.credentials_expires_at");
verify(storage).remove("com.auth0.credentials_can_refresh");
verify(storage).remove("com.auth0.manager_key_alias");
verifyNoMoreInteractions(storage);
}

Expand All @@ -586,6 +591,7 @@ public void shouldHaveCredentialsWhenTokenHasNotExpired() {
when(storage.retrieveLong("com.auth0.credentials_expires_at")).thenReturn(expirationTime);
when(storage.retrieveBoolean("com.auth0.credentials_can_refresh")).thenReturn(false);
when(storage.retrieveString("com.auth0.credentials")).thenReturn("{\"id_token\":\"idToken\"}");
when(storage.retrieveString("com.auth0.manager_key_alias")).thenReturn(SecureCredentialsManager.KEY_ALIAS);
assertThat(manager.hasValidCredentials(), is(true));

when(storage.retrieveString("com.auth0.credentials")).thenReturn("{\"access_token\":\"accessToken\"}");
Expand All @@ -598,6 +604,7 @@ public void shouldNotHaveCredentialsWhenTokenHasExpiredAndNoRefreshTokenIsAvaila
when(storage.retrieveLong("com.auth0.credentials_expires_at")).thenReturn(expirationTime);
when(storage.retrieveBoolean("com.auth0.credentials_can_refresh")).thenReturn(false);
when(storage.retrieveString("com.auth0.credentials")).thenReturn("{\"id_token\":\"idToken\"}");
when(storage.retrieveString("com.auth0.manager_key_alias")).thenReturn(SecureCredentialsManager.KEY_ALIAS);
assertThat(manager.hasValidCredentials(), is(false));

when(storage.retrieveString("com.auth0.credentials")).thenReturn("{\"access_token\":\"accessToken\"}");
Expand All @@ -610,6 +617,7 @@ public void shouldHaveCredentialsWhenTokenHasExpiredButRefreshTokenIsAvailable()
when(storage.retrieveLong("com.auth0.credentials_expires_at")).thenReturn(expirationTime);
when(storage.retrieveBoolean("com.auth0.credentials_can_refresh")).thenReturn(true);
when(storage.retrieveString("com.auth0.credentials")).thenReturn("{\"id_token\":\"idToken\", \"refresh_token\":\"refreshToken\"}");
when(storage.retrieveString("com.auth0.manager_key_alias")).thenReturn(SecureCredentialsManager.KEY_ALIAS);
assertThat(manager.hasValidCredentials(), is(true));

when(storage.retrieveString("com.auth0.credentials")).thenReturn("{\"access_token\":\"accessToken\", \"refresh_token\":\"refreshToken\"}");
Expand All @@ -619,10 +627,37 @@ public void shouldHaveCredentialsWhenTokenHasExpiredButRefreshTokenIsAvailable()
@Test
public void shouldNotHaveCredentialsWhenAccessTokenAndIdTokenAreMissing() {
when(storage.retrieveString("com.auth0.credentials")).thenReturn("{\"token_type\":\"type\", \"refresh_token\":\"refreshToken\"}");
when(storage.retrieveString("com.auth0.manager_key_alias")).thenReturn(SecureCredentialsManager.KEY_ALIAS);

assertFalse(manager.hasValidCredentials());
}

@Test
public void shouldNotHaveCredentialsWhenTheAliasUsedHasNotBeenMigratedYet() {
long expirationTime = CredentialsMock.CURRENT_TIME_MS + 123456L * 1000;
when(storage.retrieveLong("com.auth0.credentials_expires_at")).thenReturn(expirationTime);
when(storage.retrieveBoolean("com.auth0.credentials_can_refresh")).thenReturn(false);
when(storage.retrieveString("com.auth0.credentials")).thenReturn("{\"id_token\":\"idToken\"}");
when(storage.retrieveString("com.auth0.manager_key_alias")).thenReturn("old_alias");
assertThat(manager.hasValidCredentials(), is(false));

when(storage.retrieveString("com.auth0.credentials")).thenReturn("{\"access_token\":\"accessToken\"}");
assertThat(manager.hasValidCredentials(), is(false));
}

@Test
public void shouldNotHaveCredentialsWhenTheAliasUsedHasNotBeenSetYet() {
long expirationTime = CredentialsMock.CURRENT_TIME_MS + 123456L * 1000;
when(storage.retrieveLong("com.auth0.credentials_expires_at")).thenReturn(expirationTime);
when(storage.retrieveBoolean("com.auth0.credentials_can_refresh")).thenReturn(false);
when(storage.retrieveString("com.auth0.credentials")).thenReturn("{\"id_token\":\"idToken\"}");
when(storage.retrieveString("com.auth0.manager_key_alias")).thenReturn(null);
assertThat(manager.hasValidCredentials(), is(false));

when(storage.retrieveString("com.auth0.credentials")).thenReturn("{\"access_token\":\"accessToken\"}");
assertThat(manager.hasValidCredentials(), is(false));
}

/*
* Authentication tests
*/
Expand Down Expand Up @@ -860,6 +895,7 @@ private String insertTestCredentials(boolean hasIdToken, boolean hasAccessToken,
when(storage.retrieveString("com.auth0.credentials")).thenReturn(encoded);
when(storage.retrieveLong("com.auth0.credentials_expires_at")).thenReturn(willExpireAt != null ? willExpireAt.getTime() : null);
when(storage.retrieveBoolean("com.auth0.credentials_can_refresh")).thenReturn(hasRefreshToken);
when(storage.retrieveString("com.auth0.manager_key_alias")).thenReturn(SecureCredentialsManager.KEY_ALIAS);
return storedJson;
}

Expand Down

0 comments on commit bad61f1

Please sign in to comment.