Implemented encrypting Room database, but storing password just in plain text yet
This commit is contained in:
parent
20c32dbd7e
commit
0a6fa8e01a
|
@ -24,9 +24,7 @@ open class LandingActivity : AppCompatActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
val authenticationType = authenticationService.getAuthenticationType()
|
if (authenticationService.authenticationType == AuthenticationType.None) {
|
||||||
|
|
||||||
if (authenticationType == AuthenticationType.None) {
|
|
||||||
launchActivity(MainActivity::class.java)
|
launchActivity(MainActivity::class.java)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package net.dankito.banking.ui.android.activities
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.widget.Toast
|
||||||
import kotlinx.android.synthetic.main.activity_login.*
|
import kotlinx.android.synthetic.main.activity_login.*
|
||||||
import net.dankito.banking.ui.android.MainActivity
|
import net.dankito.banking.ui.android.MainActivity
|
||||||
import net.dankito.banking.ui.android.R
|
import net.dankito.banking.ui.android.R
|
||||||
|
@ -48,8 +49,11 @@ open class LoginActivity : BaseActivity() {
|
||||||
|
|
||||||
|
|
||||||
protected open fun checkEnteredPasswordAndLogIn() {
|
protected open fun checkEnteredPasswordAndLogIn() {
|
||||||
if (authenticationService.isCorrectUserPassword(edtxtLoginPassword.text)) {
|
val enteredPassword = edtxtLoginPassword.text
|
||||||
logIn()
|
|
||||||
|
if (authenticationService.isCorrectUserPassword(enteredPassword)) {
|
||||||
|
authenticationService.userLoggedInWithPassword(enteredPassword)
|
||||||
|
navigateToMainActivity()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Toast.makeText(this, R.string.activity_login_incorrect_password_entered, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, R.string.activity_login_incorrect_password_entered, Toast.LENGTH_SHORT).show()
|
||||||
|
@ -57,10 +61,11 @@ open class LoginActivity : BaseActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun biometricAuthenticationSuccessful() {
|
protected open fun biometricAuthenticationSuccessful() {
|
||||||
logIn()
|
authenticationService.userLoggedInWithBiometricAuthentication()
|
||||||
|
navigateToMainActivity()
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun logIn() {
|
protected open fun navigateToMainActivity() {
|
||||||
navigateToActivity(MainActivity::class.java)
|
navigateToActivity(MainActivity::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
package net.dankito.banking.ui.android.authentication
|
package net.dankito.banking.ui.android.authentication
|
||||||
|
|
||||||
|
import net.dankito.banking.persistence.IBankingPersistence
|
||||||
import net.dankito.banking.util.ISerializer
|
import net.dankito.banking.util.ISerializer
|
||||||
import net.dankito.utils.multiplatform.File
|
import net.dankito.utils.multiplatform.File
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
|
|
||||||
open class AuthenticationService(
|
open class AuthenticationService(
|
||||||
protected val biometricAuthenticationService: IBiometricAuthenticationService,
|
protected open val biometricAuthenticationService: IBiometricAuthenticationService,
|
||||||
protected val dataFolder: File,
|
protected open val persistence: IBankingPersistence,
|
||||||
protected val serializer: ISerializer
|
protected open val dataFolder: File,
|
||||||
|
protected open val serializer: ISerializer
|
||||||
) {
|
) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -29,11 +31,40 @@ open class AuthenticationService(
|
||||||
|
|
||||||
init {
|
init {
|
||||||
authenticationType = loadAuthenticationType()
|
authenticationType = loadAuthenticationType()
|
||||||
|
|
||||||
|
if (authenticationType == AuthenticationType.None) {
|
||||||
|
val authenticationSettings = loadAuthenticationSettings()
|
||||||
|
|
||||||
|
if (authenticationSettings == null) { // first app run -> create a default password
|
||||||
|
removeAppProtection()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
openDatabase(authenticationSettings)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
open fun userLoggedInWithBiometricAuthentication() {
|
||||||
|
loadAuthenticationSettings()?.let {
|
||||||
|
openDatabase(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun userLoggedInWithPassword(enteredPassword: String) {
|
||||||
|
openDatabase(enteredPassword)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun openDatabase(authenticationSettings: AuthenticationSettings) {
|
||||||
|
openDatabase(authenticationSettings.userPassword)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun openDatabase(password: String?) {
|
||||||
|
persistence.decryptData(password)
|
||||||
|
}
|
||||||
|
|
||||||
open fun setAuthenticationMethodToBiometric() {
|
open fun setAuthenticationMethodToBiometric() {
|
||||||
if (saveUserPasswordIfChanged(null)) {
|
if (saveNewUserPassword(generateRandomPassword())) {
|
||||||
if (saveAuthenticationType(AuthenticationType.Biometric)) {
|
if (saveAuthenticationType(AuthenticationType.Biometric)) {
|
||||||
authenticationType = AuthenticationType.Biometric
|
authenticationType = AuthenticationType.Biometric
|
||||||
}
|
}
|
||||||
|
@ -41,7 +72,7 @@ open class AuthenticationService(
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun setAuthenticationMethodToPassword(newPassword: String) {
|
open fun setAuthenticationMethodToPassword(newPassword: String) {
|
||||||
if (saveUserPasswordIfChanged(newPassword)) {
|
if (saveNewUserPassword(newPassword)) {
|
||||||
if (saveAuthenticationType(AuthenticationType.Password)) {
|
if (saveAuthenticationType(AuthenticationType.Password)) {
|
||||||
authenticationType = AuthenticationType.Password
|
authenticationType = AuthenticationType.Password
|
||||||
}
|
}
|
||||||
|
@ -49,7 +80,7 @@ open class AuthenticationService(
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun removeAppProtection() {
|
open fun removeAppProtection() {
|
||||||
if (saveUserPasswordIfChanged(null)) {
|
if (saveNewUserPassword(generateRandomPassword())) {
|
||||||
if (saveAuthenticationType(AuthenticationType.None)) {
|
if (saveAuthenticationType(AuthenticationType.None)) {
|
||||||
authenticationType = AuthenticationType.None
|
authenticationType = AuthenticationType.None
|
||||||
}
|
}
|
||||||
|
@ -103,18 +134,24 @@ open class AuthenticationService(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected open fun saveUserPasswordIfChanged(userPassword: String?): Boolean {
|
protected open fun saveNewUserPassword(newPassword: String?): Boolean {
|
||||||
val settings = loadOrCreateDefaultAuthenticationSettings()
|
val settings = loadOrCreateDefaultAuthenticationSettings()
|
||||||
|
val currentPassword = settings.userPassword
|
||||||
|
|
||||||
if (settings.userPassword != userPassword) {
|
if (currentPassword != newPassword) {
|
||||||
settings.userPassword = userPassword
|
settings.userPassword = newPassword
|
||||||
|
|
||||||
return saveAuthenticationSettings(settings)
|
if (saveAuthenticationSettings(settings)) {
|
||||||
|
persistence.changePassword(currentPassword, newPassword) // TODO: actually this is bad. If changing password fails then password is saved in AuthenticationSettings but DB has a different password
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
protected open fun loadOrCreateDefaultAuthenticationSettings(): AuthenticationSettings {
|
protected open fun loadOrCreateDefaultAuthenticationSettings(): AuthenticationSettings {
|
||||||
return loadAuthenticationSettings() ?: AuthenticationSettings(null)
|
return loadAuthenticationSettings() ?: AuthenticationSettings(null)
|
||||||
}
|
}
|
||||||
|
@ -151,4 +188,20 @@ open class AuthenticationService(
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
open fun generateRandomPassword(): String {
|
||||||
|
return generateRandomPassword(30)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun generateRandomPassword(passwordLength: Int): String {
|
||||||
|
val dictionary = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789§±!@#$%^&*-_=+;:|/?.>,<"
|
||||||
|
|
||||||
|
val passwordBuilder = StringBuilder()
|
||||||
|
IntRange(0, passwordLength).forEach {
|
||||||
|
passwordBuilder.append(dictionary.random())
|
||||||
|
}
|
||||||
|
|
||||||
|
return passwordBuilder.toString()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package net.dankito.banking.ui.android.authentication
|
||||||
|
|
||||||
|
|
||||||
|
open class AuthenticationSettings(
|
||||||
|
var userPassword: String? = null
|
||||||
|
)
|
|
@ -1,12 +1,12 @@
|
||||||
package net.dankito.banking.ui.android.authentication
|
package net.dankito.banking.ui.android.authentication
|
||||||
|
|
||||||
|
|
||||||
enum class AuthenticationType {
|
enum class AuthenticationType(internal val rawValue: Int) {
|
||||||
|
|
||||||
None,
|
None(3),
|
||||||
|
|
||||||
Password,
|
Password(7),
|
||||||
|
|
||||||
Biometric
|
Biometric(9)
|
||||||
|
|
||||||
}
|
}
|
|
@ -89,8 +89,9 @@ class BankingModule(private val applicationContext: Context) {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun provideAuthenticationService(biometricAuthenticationService: IBiometricAuthenticationService, @Named(DataFolderKey) dataFolder: File, serializer: ISerializer) : AuthenticationService {
|
fun provideAuthenticationService(biometricAuthenticationService: IBiometricAuthenticationService, persistence: IBankingPersistence,
|
||||||
return AuthenticationService(biometricAuthenticationService, dataFolder, serializer)
|
@Named(DataFolderKey) dataFolder: File, serializer: ISerializer) : AuthenticationService {
|
||||||
|
return AuthenticationService(biometricAuthenticationService, persistence, dataFolder, serializer)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
|
Loading…
Reference in New Issue