From ac725bcc33344065c3086ec02bc6d779bbbce59d Mon Sep 17 00:00:00 2001 From: murjune Date: Mon, 29 Jan 2024 04:37:35 +0900 Subject: [PATCH] =?UTF-8?q?[refactor]=20Preference=20=EB=A7=8C=EB=93=9C?= =?UTF-8?q?=EB=8A=94=20=EB=A1=9C=EC=A7=81=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moya/funch/datastore/PreferenceFactory.kt | 62 +++++++++++++++++++ .../funch/datastore/di/DataStoreModule.kt | 52 +--------------- 2 files changed, 65 insertions(+), 49 deletions(-) create mode 100644 core/datastore/src/main/java/com/moya/funch/datastore/PreferenceFactory.kt diff --git a/core/datastore/src/main/java/com/moya/funch/datastore/PreferenceFactory.kt b/core/datastore/src/main/java/com/moya/funch/datastore/PreferenceFactory.kt new file mode 100644 index 00000000..7e7d406e --- /dev/null +++ b/core/datastore/src/main/java/com/moya/funch/datastore/PreferenceFactory.kt @@ -0,0 +1,62 @@ +package com.moya.funch.datastore + +import android.content.Context +import android.content.SharedPreferences +import androidx.security.crypto.EncryptedSharedPreferences +import androidx.security.crypto.MasterKey +import com.moja.funch.datastore.BuildConfig +import dagger.hilt.android.qualifiers.ApplicationContext +import java.security.GeneralSecurityException +import java.security.KeyStore +import javax.inject.Inject + +class PreferenceFactory @Inject constructor( + @ApplicationContext private val context: Context, +) { + fun create(): SharedPreferences { + return if (BuildConfig.DEBUG) { + context.getSharedPreferences(DEBUG_DATASTORE_KEY, Context.MODE_PRIVATE) + } else { + try { + createEncryptedSharedPreferences(DATASTORE_KEY, context) + } catch (e: GeneralSecurityException) { + deleteMasterKeyEntry() + deletePreference(DATASTORE_KEY, context) + createEncryptedSharedPreferences(DATASTORE_KEY, context) + } + } + } + + private fun createEncryptedSharedPreferences( + fileName: String, + context: Context, + ): SharedPreferences { + return EncryptedSharedPreferences.create( + context, + fileName, + MasterKey.Builder(context, MasterKey.DEFAULT_MASTER_KEY_ALIAS) + .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) + .build(), + EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, + EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM + + ) + } + + private fun deletePreference(fileName: String, context: Context) { + context.deleteSharedPreferences(fileName) + } + + private fun deleteMasterKeyEntry() { + KeyStore.getInstance(ANDROID_KEY_STORE).apply { + load(null) + deleteEntry(MasterKey.DEFAULT_MASTER_KEY_ALIAS) + } + } + + companion object { + private const val DEBUG_DATASTORE_KEY = "DEBUG_DATASTORE_KEY" + private const val DATASTORE_KEY = "DATASTORE_KEY" + private const val ANDROID_KEY_STORE = "AndroidKeyStore" + } +} diff --git a/core/datastore/src/main/java/com/moya/funch/datastore/di/DataStoreModule.kt b/core/datastore/src/main/java/com/moya/funch/datastore/di/DataStoreModule.kt index 31c7fb8d..d1bf52b9 100644 --- a/core/datastore/src/main/java/com/moya/funch/datastore/di/DataStoreModule.kt +++ b/core/datastore/src/main/java/com/moya/funch/datastore/di/DataStoreModule.kt @@ -1,71 +1,25 @@ package com.moya.funch.datastore.di -import android.content.Context import android.content.SharedPreferences -import androidx.security.crypto.EncryptedSharedPreferences -import androidx.security.crypto.MasterKey -import com.moja.funch.datastore.BuildConfig import com.moya.funch.datastore.DefaultUserCodeDataStore +import com.moya.funch.datastore.PreferenceFactory import com.moya.funch.datastore.UserCodeDataStore import dagger.Binds import dagger.Module import dagger.Provides import dagger.hilt.InstallIn -import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent -import java.security.GeneralSecurityException -import java.security.KeyStore import javax.inject.Singleton @Module @InstallIn(SingletonComponent::class) object DataStoreModule { - private const val DEBUG_DATASTORE_KEY = "DEBUG_DATASTORE_KEY" - private const val DATASTORE_KEY = "DATASTORE_KEY" - private const val ANDROID_KEY_STORE = "AndroidKeyStore" @Provides @Singleton fun provideAppPreferences( - @ApplicationContext context: Context, - ): SharedPreferences = if (BuildConfig.DEBUG) { - context.getSharedPreferences(DEBUG_DATASTORE_KEY, Context.MODE_PRIVATE) - } else { - try { - createEncryptedSharedPreferences(DATASTORE_KEY, context) - } catch (e: GeneralSecurityException) { - deleteMasterKeyEntry() - deletePreference(DATASTORE_KEY, context) - createEncryptedSharedPreferences(DATASTORE_KEY, context) - } - } - - private fun deletePreference(fileName: String, context: Context) { - context.deleteSharedPreferences(fileName) - } - - private fun deleteMasterKeyEntry() { - KeyStore.getInstance(ANDROID_KEY_STORE).apply { - load(null) - deleteEntry(MasterKey.DEFAULT_MASTER_KEY_ALIAS) - } - } - - private fun createEncryptedSharedPreferences( - fileName: String, - context: Context, - ): SharedPreferences { - return EncryptedSharedPreferences.create( - context, - fileName, - MasterKey.Builder(context, MasterKey.DEFAULT_MASTER_KEY_ALIAS) - .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) - .build(), - EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, - EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM - - ) - } + factory: PreferenceFactory, + ): SharedPreferences = factory.create() @Module @InstallIn(SingletonComponent::class)