소스 검색

add SecurityTokenService - load/save access token in secure place
add also SecurityTokenService for DI in UI test

MrOzOn 5 년 전
부모
커밋
0e746a0d6d

+ 3 - 2
app/src/main/java/com/mrozon/healthdiary/di/FacadeComponent.kt

@@ -6,12 +6,12 @@ import com.mrozon.core_api.db.DatabaseProvider
 import com.mrozon.core_api.network.NetworkProvider
 import com.mrozon.core_api.providers.AppProvider
 import com.mrozon.core_api.providers.ProvidersFacade
-import com.mrozon.core_api.viewmodel.ViewModelsFactoryProvider
+import com.mrozon.core_api.security.SecurityTokenProvider
 import com.mrozon.healthdiary.App
 import dagger.Component
 
 @Component(
-    dependencies = [AppProvider::class, DatabaseProvider::class, NetworkProvider::class],
+    dependencies = [AppProvider::class, DatabaseProvider::class, NetworkProvider::class, SecurityTokenProvider::class],
     modules = [NavigationModule::class]
 )
 interface FacadeComponent : ProvidersFacade {
@@ -23,6 +23,7 @@ interface FacadeComponent : ProvidersFacade {
                 .appProvider(AppComponent.create(application))
                 .databaseProvider(CoreProvidersFactory.createDatabaseBuilder(AppComponent.create(application)))
                 .networkProvider(CoreProvidersFactory.createNetworkBuilder())
+                .securityTokenProvider(CoreProvidersFactory.createSecurityTokenBuilder(AppComponent.create(application)))
                 .build()
     }
 

+ 5 - 0
core/src/main/java/com/mrozon/core/CoreProvidersFactory.kt

@@ -3,6 +3,8 @@ package com.mrozon.core
 import com.mrozon.core_api.db.DatabaseProvider
 import com.mrozon.core_api.network.NetworkProvider
 import com.mrozon.core_api.providers.AppProvider
+import com.mrozon.core_api.security.SecurityTokenProvider
+import com.mrozon.core_impl.crypto.DaggerSecurityTokenComponent
 import com.mrozon.core_impl.db.DaggerDatabaseComponent
 import com.mrozon.core_impl.network.DaggerNetworkComponent
 
@@ -15,4 +17,7 @@ object CoreProvidersFactory {
         return DaggerNetworkComponent.create()
     }
 
+    fun createSecurityTokenBuilder(appProvider: AppProvider): SecurityTokenProvider {
+        return DaggerSecurityTokenComponent.builder().appProvider(appProvider).build()
+    }
 }

+ 3 - 1
core_api/src/main/java/com/mrozon/core_api/providers/ProvidersFacade.kt

@@ -3,5 +3,7 @@ package com.mrozon.core_api.providers
 import com.mrozon.core_api.db.DatabaseProvider
 import com.mrozon.core_api.navigation.NavigatorProvider
 import com.mrozon.core_api.network.NetworkProvider
+import com.mrozon.core_api.security.SecurityTokenProvider
 
-interface ProvidersFacade : NetworkProvider, DatabaseProvider, AppProvider, NavigatorProvider
+interface ProvidersFacade : NetworkProvider, DatabaseProvider, AppProvider,
+    NavigatorProvider, SecurityTokenProvider

+ 5 - 0
core_api/src/main/java/com/mrozon/core_api/security/SecurityTokenProvider.kt

@@ -0,0 +1,5 @@
+package com.mrozon.core_api.security
+
+interface SecurityTokenProvider {
+    fun provideSecurityTokenService(): SecurityTokenService
+}

+ 6 - 0
core_api/src/main/java/com/mrozon/core_api/security/SecurityTokenService.kt

@@ -0,0 +1,6 @@
+package com.mrozon.core_api.security
+
+interface SecurityTokenService {
+    fun loadAccessToken(): String
+    fun saveAccessToken(string: String)
+}

+ 1 - 0
core_impl/build.gradle

@@ -41,6 +41,7 @@ dependencies {
     implementation gson
     implementation converterGson
     implementation navigationFragment
+    implementation securityCrypto
 
     implementation fileTree(dir: 'libs', include: ['*.jar'])
     implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

+ 13 - 0
core_impl/src/main/java/com/mrozon/core_impl/crypto/SecurityTokenComponent.kt

@@ -0,0 +1,13 @@
+package com.mrozon.core_impl.crypto
+
+import com.mrozon.core_api.providers.AppProvider
+import com.mrozon.core_api.security.SecurityTokenProvider
+import dagger.Component
+import javax.inject.Singleton
+
+@Singleton
+@Component(
+    dependencies = [AppProvider::class],
+    modules = [SecurityTokenModule::class]
+)
+interface SecurityTokenComponent: SecurityTokenProvider

+ 19 - 0
core_impl/src/main/java/com/mrozon/core_impl/crypto/SecurityTokenModule.kt

@@ -0,0 +1,19 @@
+package com.mrozon.core_impl.crypto
+
+import android.content.SharedPreferences
+import androidx.security.crypto.EncryptedSharedPreferences
+import androidx.security.crypto.MasterKey
+import com.mrozon.core_api.navigation.SplashNavigator
+import com.mrozon.core_api.security.SecurityTokenService
+import dagger.Binds
+import dagger.Module
+import dagger.Reusable
+
+@Module
+interface SecurityTokenModule {
+
+    @Reusable
+    @Binds
+    fun  provideSecurityTokenService(service: SecurityTokenServiceImpl): SecurityTokenService
+
+}

+ 43 - 0
core_impl/src/main/java/com/mrozon/core_impl/crypto/SecurityTokenServiceImpl.kt

@@ -0,0 +1,43 @@
+package com.mrozon.core_impl.crypto
+
+import android.content.Context
+import android.content.SharedPreferences
+import androidx.security.crypto.EncryptedSharedPreferences
+import androidx.security.crypto.MasterKey
+import com.mrozon.core_api.security.SecurityTokenProvider
+import com.mrozon.core_api.security.SecurityTokenService
+import javax.inject.Inject
+
+class SecurityTokenServiceImpl @Inject constructor(
+    context: Context
+): SecurityTokenService {
+
+    companion object {
+        const val FILE_NAME = "access_token"
+    }
+
+    private var ssp: SharedPreferences
+
+    init {
+        val masterKey = MasterKey.Builder(context)
+            .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
+            .build()
+        ssp = EncryptedSharedPreferences.create(
+            context,
+            FILE_NAME,
+            masterKey,
+            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
+            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
+        )
+    }
+
+    override fun loadAccessToken(): String {
+        return ssp.getString("token","")?:""
+    }
+
+    override fun saveAccessToken(string: String) {
+        ssp.edit()
+            .putString("token",string)
+            .apply()
+    }
+}

+ 3 - 1
feature_auth/src/androidTest/java/com/mrozon/feature_auth/di/FacadeComponent.kt

@@ -6,12 +6,13 @@ import com.mrozon.core_api.db.DatabaseProvider
 import com.mrozon.core_api.network.NetworkProvider
 import com.mrozon.core_api.providers.AppProvider
 import com.mrozon.core_api.providers.ProvidersFacade
+import com.mrozon.core_api.security.SecurityTokenProvider
 import com.mrozon.core_api.viewmodel.ViewModelsFactoryProvider
 import com.mrozon.feature_auth.presentation.TestApp
 import dagger.Component
 
 @Component(
-    dependencies = [AppProvider::class, DatabaseProvider::class, NetworkProvider::class],
+    dependencies = [AppProvider::class, DatabaseProvider::class, NetworkProvider::class, SecurityTokenProvider::class],
     modules = [NavigationModule::class]
 )
 interface FacadeComponent : ProvidersFacade {
@@ -23,6 +24,7 @@ interface FacadeComponent : ProvidersFacade {
                 .appProvider(AppComponent.create(application))
                 .databaseProvider(CoreProvidersFactory.createDatabaseBuilder(AppComponent.create(application)))
                 .networkProvider(CoreProvidersFactory.createNetworkBuilder())
+                .securityTokenProvider(CoreProvidersFactory.createSecurityTokenBuilder(AppComponent.create(application)))
                 .build()
     }
 

+ 3 - 1
scripts/deps_versions.gradle

@@ -24,6 +24,7 @@ ext {
     robolectricVersion = "4.4"
     androidXCoreTestVersion = "2.1.0"
     androidXTestVersion = "1.1.0"
+    securityCryptoVersion = "1.1.0-alpha02"
 
     // DI
     dagger = "com.google.dagger:dagger:$daggerVersion"
@@ -71,5 +72,6 @@ ext {
     androidxCore = "androidx.core:core-ktx:$androidxCoreVersion"
     // Kotlin
     kotlinStdlib = "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
-
+    //Crytpo
+    securityCrypto = "androidx.security:security-crypto:$securityCryptoVersion"
 }