Settings: Save server, username, password
This commit is contained in:
@@ -61,6 +61,7 @@ dependencies {
|
||||
|
||||
// Kordophone lib
|
||||
implementation project(':backend')
|
||||
implementation 'androidx.security:security-crypto-ktx:1.1.0-alpha06'
|
||||
|
||||
// Navigation
|
||||
def nav_version = "2.6.0"
|
||||
|
||||
@@ -98,8 +98,8 @@ fun SettingsFormView(
|
||||
})
|
||||
}
|
||||
|
||||
var usernameInput by remember { mutableStateOf(TextFieldValue()) }
|
||||
var passwordInput by remember { mutableStateOf(TextFieldValue()) }
|
||||
var usernameInput by remember { mutableStateOf(TextFieldValue(userName.value)) }
|
||||
var passwordInput by remember { mutableStateOf(TextFieldValue(password.value)) }
|
||||
SettingsTextField(
|
||||
name = "Authentication",
|
||||
icon = R.drawable.account_circle,
|
||||
|
||||
@@ -23,6 +23,15 @@ class SettingsViewModel @Inject constructor(
|
||||
private val _passwordPreference: MutableStateFlow<String> = MutableStateFlow("")
|
||||
var passwordPreference = _passwordPreference.asStateFlow()
|
||||
|
||||
init {
|
||||
val serverConfig = serverConfigRepository.serverConfig.value
|
||||
serverConfig.serverName?.let { _serverPreference.value = it }
|
||||
serverConfig.authentication?.let {
|
||||
_usernamePreference.value = it.username
|
||||
_passwordPreference.value = it.password
|
||||
}
|
||||
}
|
||||
|
||||
fun saveServerPreference(serverName: String) {
|
||||
_serverPreference.value = serverName
|
||||
|
||||
@@ -36,7 +45,7 @@ class SettingsViewModel @Inject constructor(
|
||||
_passwordPreference.value = password
|
||||
|
||||
serverConfigRepository.applyConfig {
|
||||
authentication = ServerAuthentication(username, password)
|
||||
this.authentication = ServerAuthentication(username, password)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +1,102 @@
|
||||
package net.buzzert.kordophonedroid.ui.shared
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import androidx.core.content.edit
|
||||
import androidx.security.crypto.EncryptedSharedPreferences
|
||||
import androidx.security.crypto.MasterKey
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import java.lang.reflect.Constructor
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
|
||||
data class ServerConfig(
|
||||
var serverName: String? = null,
|
||||
var authentication: ServerAuthentication? = null,
|
||||
) {
|
||||
companion object {
|
||||
private const val SHARED_PREF_NAME = "KordophonePreferences"
|
||||
|
||||
fun loadFromSettings(context: Context): ServerConfig {
|
||||
val prefs = getSharedPreferences(context)
|
||||
return ServerConfig(
|
||||
serverName = prefs.getString("serverName", null),
|
||||
authentication = ServerAuthentication.loadFromEncryptedSettings(context)
|
||||
)
|
||||
}
|
||||
|
||||
private fun getSharedPreferences(context: Context): SharedPreferences {
|
||||
return context.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE)
|
||||
}
|
||||
}
|
||||
|
||||
fun saveToSettings(context: Context) {
|
||||
val prefs = getSharedPreferences(context)
|
||||
prefs.edit {
|
||||
putString("serverName", serverName)
|
||||
apply()
|
||||
}
|
||||
|
||||
authentication?.saveToEncryptedSettings(context)
|
||||
}
|
||||
}
|
||||
|
||||
data class ServerAuthentication(
|
||||
val username: String,
|
||||
val password: String,
|
||||
) {
|
||||
companion object {
|
||||
fun loadFromEncryptedSettings(context: Context): ServerAuthentication? {
|
||||
val prefs = getEncryptedSharedPreferences(context)
|
||||
|
||||
val username = prefs.getString("username", null)
|
||||
val password = prefs.getString("password", null)
|
||||
if (username != null && password != null) {
|
||||
return ServerAuthentication(username, password)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getEncryptedSharedPreferences(context: Context): SharedPreferences {
|
||||
val masterKey = MasterKey.Builder(context)
|
||||
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
|
||||
.build()
|
||||
|
||||
return EncryptedSharedPreferences(
|
||||
context,
|
||||
"secrets",
|
||||
masterKey,
|
||||
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
|
||||
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun saveToEncryptedSettings(context: Context) {
|
||||
val prefs = getEncryptedSharedPreferences(context)
|
||||
prefs.edit {
|
||||
putString("username", username)
|
||||
putString("password", password)
|
||||
apply()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Singleton
|
||||
class ServerConfigRepository @Inject constructor() {
|
||||
class ServerConfigRepository @Inject constructor(
|
||||
@ApplicationContext val context: Context,
|
||||
) {
|
||||
// TODO: Initial config should be loaded from device settings.
|
||||
private val _serverConfig = MutableStateFlow(ServerConfig()) // Initial config
|
||||
private val _serverConfig = MutableStateFlow(ServerConfig.loadFromSettings(context)) // Initial config
|
||||
val serverConfig: StateFlow<ServerConfig> = _serverConfig
|
||||
|
||||
fun applyConfig(applicator: ServerConfig.() -> Unit) {
|
||||
val config = _serverConfig.value.copy()
|
||||
_serverConfig.value = config.apply(applicator)
|
||||
_serverConfig.value.saveToSettings(context)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user