From 2d3cad4803385ebc174353adf4043c573f29e901 Mon Sep 17 00:00:00 2001 From: Akshay Ayyanchira Date: Mon, 14 Apr 2025 15:39:54 -0700 Subject: [PATCH 1/2] [MOB-11167] - Simplifying the config names Internal working of Keychain at this commit stage still assumes the default is false. Hence this commit cant be merged as IterableConfig and Keychain work on different basis --- .../java/com/iterable/iterableapi/IterableApi.java | 2 +- .../com/iterable/iterableapi/IterableConfig.java | 12 ++++++------ .../com/iterable/iterableapi/IterableConfigTest.kt | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/iterableapi/src/main/java/com/iterable/iterableapi/IterableApi.java b/iterableapi/src/main/java/com/iterable/iterableapi/IterableApi.java index 1422a818e..793228594 100644 --- a/iterableapi/src/main/java/com/iterable/iterableapi/IterableApi.java +++ b/iterableapi/src/main/java/com/iterable/iterableapi/IterableApi.java @@ -144,7 +144,7 @@ IterableKeychain getKeychain() { } if (keychain == null) { try { - keychain = new IterableKeychain(getMainActivityContext(), config.decryptionFailureHandler, null, config.disableKeychainEncryption); + keychain = new IterableKeychain(getMainActivityContext(), config.decryptionFailureHandler, null, config.keychainEncryption); } catch (Exception e) { IterableLogger.e(TAG, "Failed to create IterableKeychain", e); } diff --git a/iterableapi/src/main/java/com/iterable/iterableapi/IterableConfig.java b/iterableapi/src/main/java/com/iterable/iterableapi/IterableConfig.java index d8b82dd8a..3c2d79641 100644 --- a/iterableapi/src/main/java/com/iterable/iterableapi/IterableConfig.java +++ b/iterableapi/src/main/java/com/iterable/iterableapi/IterableConfig.java @@ -97,7 +97,7 @@ public class IterableConfig { * When set to true, disables encryption for keychain storage. * By default, encryption is enabled for storing sensitive user data. */ - final boolean disableKeychainEncryption; + final boolean keychainEncryption; /** * Handler for decryption failures of PII information. @@ -127,7 +127,7 @@ private IterableConfig(Builder builder) { dataRegion = builder.dataRegion; useInMemoryStorageForInApps = builder.useInMemoryStorageForInApps; enableEmbeddedMessaging = builder.enableEmbeddedMessaging; - disableKeychainEncryption = builder.disableKeychainEncryption; + keychainEncryption = builder.keychainEncryption; decryptionFailureHandler = builder.decryptionFailureHandler; mobileFrameworkInfo = builder.mobileFrameworkInfo; } @@ -148,7 +148,7 @@ public static class Builder { private IterableDataRegion dataRegion = IterableDataRegion.US; private boolean useInMemoryStorageForInApps = false; private boolean enableEmbeddedMessaging = false; - private boolean disableKeychainEncryption = false; + private boolean keychainEncryption = true; private IterableDecryptionFailureHandler decryptionFailureHandler; private IterableAPIMobileFrameworkInfo mobileFrameworkInfo; @@ -314,11 +314,11 @@ public Builder setEnableEmbeddedMessaging(boolean enableEmbeddedMessaging) { /** * When set to true, disables encryption for Iterable's keychain storage. * By default, encryption is enabled for storing sensitive user data. - * @param disableKeychainEncryption Whether to disable encryption for keychain + * @param keychainEncryption Whether to disable encryption for keychain */ @NonNull - public Builder setDisableKeychainEncryption(boolean disableKeychainEncryption) { - this.disableKeychainEncryption = disableKeychainEncryption; + public Builder setKeychainEncryption(boolean keychainEncryption) { + this.keychainEncryption = keychainEncryption; return this; } diff --git a/iterableapi/src/test/java/com/iterable/iterableapi/IterableConfigTest.kt b/iterableapi/src/test/java/com/iterable/iterableapi/IterableConfigTest.kt index 0781f11b7..c64476107 100644 --- a/iterableapi/src/test/java/com/iterable/iterableapi/IterableConfigTest.kt +++ b/iterableapi/src/test/java/com/iterable/iterableapi/IterableConfigTest.kt @@ -25,14 +25,14 @@ class IterableConfigTest { fun defaultDisableKeychainEncryption() { val configBuilder: IterableConfig.Builder = IterableConfig.Builder() val config: IterableConfig = configBuilder.build() - assertFalse(config.disableKeychainEncryption) + assertTrue(config.keychainEncryption) } @Test fun setDisableKeychainEncryption() { val configBuilder: IterableConfig.Builder = IterableConfig.Builder() - .setDisableKeychainEncryption(true) + .setKeychainEncryption(false) val config: IterableConfig = configBuilder.build() - assertTrue(config.disableKeychainEncryption) + assertFalse(config.keychainEncryption) } } \ No newline at end of file From 7d453b7d79aa2117e6dd1079c89c04ee0db74891 Mon Sep 17 00:00:00 2001 From: Akshay Ayyanchira Date: Mon, 14 Apr 2025 16:00:41 -0700 Subject: [PATCH 2/2] Inverting the values for simplification Inverting the defaults for easy naming. Modified the Test suite as well to be aware of defaults. --- .../iterable/iterableapi/IterableKeychain.kt | 18 +++++++++--------- .../iterableapi/IterableKeychainTest.kt | 6 ++++-- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/iterableapi/src/main/java/com/iterable/iterableapi/IterableKeychain.kt b/iterableapi/src/main/java/com/iterable/iterableapi/IterableKeychain.kt index 201e9dfbe..139bc68e1 100644 --- a/iterableapi/src/main/java/com/iterable/iterableapi/IterableKeychain.kt +++ b/iterableapi/src/main/java/com/iterable/iterableapi/IterableKeychain.kt @@ -14,7 +14,7 @@ class IterableKeychain { const val KEY_AUTH_TOKEN = "iterable-auth-token" private const val PLAINTEXT_SUFFIX = "_plaintext" private const val CRYPTO_OPERATION_TIMEOUT_MS = 500L - private const val KEY_ENCRYPTION_DISABLED = "iterable-encryption-disabled" + private const val KEY_ENCRYPTION_ENABLED = "iterable-encryption-enabled" private val cryptoExecutor = Executors.newSingleThreadExecutor() } @@ -22,23 +22,23 @@ class IterableKeychain { private var sharedPrefs: SharedPreferences internal var encryptor: IterableDataEncryptor? = null private val decryptionFailureHandler: IterableDecryptionFailureHandler? - private var encryptionDisabled: Boolean + private var encryption: Boolean @JvmOverloads constructor( context: Context, decryptionFailureHandler: IterableDecryptionFailureHandler? = null, migrator: IterableKeychainEncryptedDataMigrator? = null, - encryptionDisabled: Boolean = false + encryption: Boolean = true ) { sharedPrefs = context.getSharedPreferences( IterableConstants.SHARED_PREFS_FILE, Context.MODE_PRIVATE ) this.decryptionFailureHandler = decryptionFailureHandler - this.encryptionDisabled = encryptionDisabled || sharedPrefs.getBoolean(KEY_ENCRYPTION_DISABLED, false) + this.encryption = encryption && sharedPrefs.getBoolean(KEY_ENCRYPTION_ENABLED, true) - if (encryptionDisabled) { + if (!encryption) { IterableLogger.v(TAG, "SharedPreferences being used without encryption") } else { encryptor = IterableDataEncryptor() @@ -75,10 +75,10 @@ class IterableKeychain { .remove(KEY_EMAIL) .remove(KEY_USER_ID) .remove(KEY_AUTH_TOKEN) - .putBoolean(KEY_ENCRYPTION_DISABLED, true) + .putBoolean(KEY_ENCRYPTION_ENABLED, false) .apply() - encryptionDisabled = true + encryption = false decryptionFailureHandler?.let { handler -> val exception = e ?: Exception("Unknown decryption error") @@ -99,7 +99,7 @@ class IterableKeychain { private fun secureGet(key: String): String? { val hasPlainText = sharedPrefs.getBoolean(key + PLAINTEXT_SUFFIX, false) - if (encryptionDisabled) { + if (!encryption) { if (hasPlainText) { return sharedPrefs.getString(key, null) } else { @@ -125,7 +125,7 @@ class IterableKeychain { return } - if (encryptionDisabled) { + if (!encryption) { editor.putString(key, value).putBoolean(key + PLAINTEXT_SUFFIX, true).apply() return } diff --git a/iterableapi/src/test/java/com/iterable/iterableapi/IterableKeychainTest.kt b/iterableapi/src/test/java/com/iterable/iterableapi/IterableKeychainTest.kt index 152cc3ab7..08fb042ff 100644 --- a/iterableapi/src/test/java/com/iterable/iterableapi/IterableKeychainTest.kt +++ b/iterableapi/src/test/java/com/iterable/iterableapi/IterableKeychainTest.kt @@ -62,12 +62,14 @@ class IterableKeychainTest { // Mock migration-related SharedPreferences calls `when`(mockSharedPrefs.contains(any())).thenReturn(false) - `when`(mockSharedPrefs.getBoolean(any(), anyBoolean())).thenReturn(false) + // Mock encryption flag to be true by default + `when`(mockSharedPrefs.getBoolean(eq("iterable-encryption-enabled"), anyBoolean())).thenReturn(true) `when`(mockSharedPrefs.getString(any(), any())).thenReturn(null) // Mock editor.apply() to do nothing Mockito.doNothing().`when`(mockEditor).apply() + // Create keychain with encryption enabled (default) keychain = IterableKeychain( mockContext, mockDecryptionFailureHandler @@ -328,7 +330,7 @@ class IterableKeychainTest { mockContext, mockDecryptionFailureHandler, null, - true + false // encryption = false means encryption is disabled ) val testEmail = "test@example.com"