From fb74628aa8ec0833e4a0abe00d5dff076b093d10 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 23 Sep 2020 12:43:39 +0200 Subject: [PATCH] Protect access to pin code setting, and so remove protection to disable the pin code --- .../im/vector/app/features/pin/PinFragment.kt | 44 ---------------- .../im/vector/app/features/pin/PinMode.kt | 1 - .../settings/VectorSettingsPinFragment.kt | 14 ++--- .../VectorSettingsSecurityPrivacyFragment.kt | 51 ++++++++++++++++--- .../xml/vector_settings_security_privacy.xml | 3 +- 5 files changed, 53 insertions(+), 60 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/pin/PinFragment.kt b/vector/src/main/java/im/vector/app/features/pin/PinFragment.kt index 7aa76432b7..b6e238c2dc 100644 --- a/vector/src/main/java/im/vector/app/features/pin/PinFragment.kt +++ b/vector/src/main/java/im/vector/app/features/pin/PinFragment.kt @@ -55,54 +55,10 @@ class PinFragment @Inject constructor( super.onViewCreated(view, savedInstanceState) when (fragmentArgs.pinMode) { PinMode.CREATE -> showCreateFragment() - PinMode.DELETE -> showDeleteFragment() PinMode.AUTH -> showAuthFragment() } } - private fun showDeleteFragment() { - val encodedPin = pinCodeStore.getEncodedPin() ?: return - val authFragment = PFLockScreenFragment() - val builder = PFFLockScreenConfiguration.Builder(requireContext()) - .setUseBiometric(vectorPreferences.useBiometricsToUnlock() && pinCodeStore.getRemainingBiometricsAttemptsNumber() > 0) - .setTitle(getString(R.string.auth_pin_confirm_to_disable_title)) - .setClearCodeOnError(true) - .setMode(PFFLockScreenConfiguration.MODE_AUTH) - authFragment.setConfiguration(builder.build()) - authFragment.setEncodedPinCode(encodedPin) - authFragment.setLoginListener(object : PFLockScreenFragment.OnPFLockScreenLoginListener { - override fun onPinLoginFailed() { - onWrongPin() - } - - override fun onBiometricAuthSuccessful() { - lifecycleScope.launch { - pinCodeStore.deleteEncodedPin() - vectorBaseActivity.setResult(Activity.RESULT_OK) - vectorBaseActivity.finish() - } - } - - override fun onBiometricAuthLoginFailed() { - val remainingAttempts = pinCodeStore.onWrongBiometrics() - if (remainingAttempts <= 0) { - // Disable Biometrics - builder.setUseBiometric(false) - authFragment.setConfiguration(builder.build()) - } - } - - override fun onCodeInputSuccessful() { - lifecycleScope.launch { - pinCodeStore.deleteEncodedPin() - vectorBaseActivity.setResult(Activity.RESULT_OK) - vectorBaseActivity.finish() - } - } - }) - replaceFragment(R.id.pinFragmentContainer, authFragment) - } - private fun showCreateFragment() { val createFragment = PFLockScreenFragment() val builder = PFFLockScreenConfiguration.Builder(requireContext()) diff --git a/vector/src/main/java/im/vector/app/features/pin/PinMode.kt b/vector/src/main/java/im/vector/app/features/pin/PinMode.kt index 732b55fd58..c24ac5adf2 100644 --- a/vector/src/main/java/im/vector/app/features/pin/PinMode.kt +++ b/vector/src/main/java/im/vector/app/features/pin/PinMode.kt @@ -18,6 +18,5 @@ package im.vector.app.features.pin enum class PinMode { CREATE, - DELETE, AUTH } diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPinFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPinFragment.kt index e8f3e51b4f..f8353c31af 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPinFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPinFragment.kt @@ -24,12 +24,11 @@ import im.vector.app.R import im.vector.app.features.navigation.Navigator import im.vector.app.features.pin.PinActivity import im.vector.app.features.pin.PinCodeStore -import im.vector.app.features.pin.PinLocker import im.vector.app.features.pin.PinMode +import kotlinx.coroutines.launch import javax.inject.Inject class VectorSettingsPinFragment @Inject constructor( - private val pinLocker: PinLocker, private val pinCodeStore: PinCodeStore, private val navigator: Navigator ) : VectorSettingsBaseFragment() { @@ -50,12 +49,14 @@ class VectorSettingsPinFragment @Inject constructor( val hasPinCode = pinCodeStore.hasEncodedPin() usePinCodePref.isChecked = hasPinCode usePinCodePref.onPreferenceClickListener = Preference.OnPreferenceClickListener { - val pinMode = if (hasPinCode) { - PinMode.DELETE + if (hasPinCode) { + lifecycleScope.launch { + pinCodeStore.deleteEncodedPin() + refreshPinCodeStatus() + } } else { - PinMode.CREATE + navigator.openPinCode(this@VectorSettingsPinFragment, PinMode.CREATE) } - navigator.openPinCode(this@VectorSettingsPinFragment, pinMode) true } } @@ -64,7 +65,6 @@ class VectorSettingsPinFragment @Inject constructor( override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == PinActivity.PIN_REQUEST_CODE) { - pinLocker.unlock() refreshPinCodeStatus() } } diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt index 532ab39eb3..b99bb50559 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt @@ -29,6 +29,7 @@ import android.widget.TextView import androidx.appcompat.app.AlertDialog import androidx.core.content.ContextCompat import androidx.core.view.isVisible +import androidx.lifecycle.lifecycleScope import androidx.preference.Preference import androidx.preference.PreferenceCategory import androidx.preference.SwitchPreference @@ -52,6 +53,11 @@ import im.vector.app.features.crypto.keys.KeysExporter import im.vector.app.features.crypto.keys.KeysImporter import im.vector.app.features.crypto.keysbackup.settings.KeysBackupManageActivity import im.vector.app.features.crypto.recover.BootstrapBottomSheet +import im.vector.app.features.navigation.Navigator +import im.vector.app.features.pin.PinActivity +import im.vector.app.features.pin.PinCodeStore +import im.vector.app.features.pin.PinLocker +import im.vector.app.features.pin.PinMode import im.vector.app.features.raw.wellknown.ElementWellKnownMapper import im.vector.app.features.raw.wellknown.isE2EByDefault import im.vector.app.features.themes.ThemeUtils @@ -70,7 +76,9 @@ import javax.inject.Inject class VectorSettingsSecurityPrivacyFragment @Inject constructor( private val vectorPreferences: VectorPreferences, - private val activeSessionHolder: ActiveSessionHolder + private val activeSessionHolder: ActiveSessionHolder, + private val pinCodeStore: PinCodeStore, + private val navigator: Navigator ) : VectorSettingsBaseFragment() { override var titleRes = R.string.settings_security_and_privacy @@ -119,6 +127,10 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor( findPreference(VectorPreferences.SETTINGS_ENCRYPTION_NEVER_SENT_TO_PREFERENCE_KEY)!! } + private val openPinCodeSettingsPref by lazy { + findPreference("SETTINGS_SECURITY_PIN")!! + } + override fun onCreateRecyclerView(inflater: LayoutInflater?, parent: ViewGroup?, savedInstanceState: Bundle?): RecyclerView { return super.onCreateRecyclerView(inflater, parent, savedInstanceState).also { // Insert animation are really annoying the first time the list is shown @@ -145,11 +157,11 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor( vectorActivity.getVectorComponent() .rawService() .getWellknown(session.myUserId, object : MatrixCallback { - override fun onSuccess(data: String) { - findPreference(VectorPreferences.SETTINGS_CRYPTOGRAPHY_HS_ADMIN_DISABLED_E2E_DEFAULT)?.isVisible = - ElementWellKnownMapper.from(data)?.isE2EByDefault() == false - } - }) + override fun onSuccess(data: String) { + findPreference(VectorPreferences.SETTINGS_CRYPTOGRAPHY_HS_ADMIN_DISABLED_E2E_DEFAULT)?.isVisible = + ElementWellKnownMapper.from(data)?.isE2EByDefault() == false + } + }) } private val secureBackupCategory by lazy { @@ -252,6 +264,11 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor( } } + openPinCodeSettingsPref.setOnPreferenceClickListener { + openPinCodePreferenceScreen() + true + } + refreshXSigningStatus() secureBackupPreference.icon = activity?.let { @@ -336,6 +353,8 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor( }) } } + } else if (requestCode == PinActivity.PIN_REQUEST_CODE) { + doOpenPinCodePreferenceScreen() } else if (requestCode == REQUEST_E2E_FILE_REQUEST_CODE) { if (resultCode == Activity.RESULT_OK) { importKeys(data) @@ -343,6 +362,26 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor( } } + private fun openPinCodePreferenceScreen() { + lifecycleScope.launchWhenResumed { + val hasPinCode = pinCodeStore.hasEncodedPin() + if (hasPinCode) { + navigator.openPinCode(this@VectorSettingsSecurityPrivacyFragment, PinMode.AUTH) + } else { + doOpenPinCodePreferenceScreen() + } + } + } + + private fun doOpenPinCodePreferenceScreen() { + // TODO Avoid duplication of this code. Move it to Activity + parentFragmentManager.beginTransaction() + .setCustomAnimations(R.anim.anim_slide_in_bottom, R.anim.anim_slide_out_bottom, R.anim.anim_slide_in_bottom, R.anim.anim_slide_out_bottom) + .replace(R.id.vector_settings_page, VectorSettingsPinFragment::class.java, null) + .addToBackStack(null) + .commit() + } + private fun refreshKeysManagementSection() { // If crypto is not enabled parent section will be removed // TODO notice that this will not work when no network diff --git a/vector/src/main/res/xml/vector_settings_security_privacy.xml b/vector/src/main/res/xml/vector_settings_security_privacy.xml index 75256a5ead..fa26107edb 100644 --- a/vector/src/main/res/xml/vector_settings_security_privacy.xml +++ b/vector/src/main/res/xml/vector_settings_security_privacy.xml @@ -120,9 +120,8 @@ + android:title="@string/settings_security_application_protection_title" />