From a0b0ee2b13b72d1ec6a489150c717c8bfa863158 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Tue, 1 Sep 2020 09:49:05 -0300 Subject: [cashier] check authentication credentials against auth endpoint before accepting config This was an unannounced change at the server which removed auth from the /config endpoint. --- .../src/main/java/net/taler/cashier/Response.kt | 2 +- .../java/net/taler/cashier/config/ConfigManager.kt | 37 +++++++++++++++------- 2 files changed, 26 insertions(+), 13 deletions(-) (limited to 'cashier') diff --git a/cashier/src/main/java/net/taler/cashier/Response.kt b/cashier/src/main/java/net/taler/cashier/Response.kt index 0ad39d0..c5b1c32 100644 --- a/cashier/src/main/java/net/taler/cashier/Response.kt +++ b/cashier/src/main/java/net/taler/cashier/Response.kt @@ -55,7 +55,7 @@ class Response private constructor( } } - private val isFailure: Boolean get() = value is Failure + val isFailure: Boolean get() = value is Failure suspend fun onSuccess(block: suspend (result: T) -> Unit): Response { @Suppress("UNCHECKED_CAST") diff --git a/cashier/src/main/java/net/taler/cashier/config/ConfigManager.kt b/cashier/src/main/java/net/taler/cashier/config/ConfigManager.kt index a18073d..f83c7ba 100644 --- a/cashier/src/main/java/net/taler/cashier/config/ConfigManager.kt +++ b/cashier/src/main/java/net/taler/cashier/config/ConfigManager.kt @@ -24,7 +24,10 @@ import androidx.annotation.WorkerThread import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.security.crypto.EncryptedSharedPreferences +import androidx.security.crypto.EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV +import androidx.security.crypto.EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM import androidx.security.crypto.MasterKeys +import androidx.security.crypto.MasterKeys.AES256_GCM_SPEC import io.ktor.client.HttpClient import io.ktor.client.request.get import io.ktor.client.request.header @@ -56,11 +59,9 @@ class ConfigManager( val configDestination = ConfigFragmentDirections.actionGlobalConfigFragment() - private val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC) + private val masterKeyAlias = MasterKeys.getOrCreate(AES256_GCM_SPEC) private val prefs = EncryptedSharedPreferences.create( - PREF_NAME, masterKeyAlias, app, - EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, - EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM + PREF_NAME, masterKeyAlias, app, AES256_SIV, AES256_GCM ) internal var config = Config( @@ -111,17 +112,29 @@ class ConfigManager( } } - private suspend fun checkConfig(config: Config): Response = - withContext(Dispatchers.IO) { - val url = "${config.bankUrl}/config" - Log.d(TAG, "Checking config: $url") - response { - httpClient.get(url) { - // TODO why does that not fail already? + private suspend fun checkConfig(config: Config) = withContext(Dispatchers.IO) { + val url = "${config.bankUrl}/config" + Log.d(TAG, "Checking config: $url") + val configResponse = response { + httpClient.get(url) as ConfigResponse + } + if (configResponse.isFailure) { + configResponse + } else { + // we need to check an endpoint that requires authentication as well + // to see if the credentials are valid + val balanceResponse = response { + val authUrl = "${config.bankUrl}/accounts/${config.username}/balance" + Log.d(TAG, "Checking auth: $authUrl") + httpClient.get(authUrl) { header(Authorization, config.basicAuth) - } as ConfigResponse + } } + @Suppress("UNCHECKED_CAST") // The type doesn't matter for failures + if (balanceResponse.isFailure) balanceResponse as Response + else configResponse } + } @WorkerThread @SuppressLint("ApplySharedPref") -- cgit v1.2.3