Protect access to pin code setting, and so remove protection to disable the pin code

This commit is contained in:
Benoit Marty 2020-09-23 12:43:39 +02:00 committed by Benoit Marty
parent fdedfc954c
commit fb74628aa8
5 changed files with 53 additions and 60 deletions

View File

@ -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())

View File

@ -18,6 +18,5 @@ package im.vector.app.features.pin
enum class PinMode {
CREATE,
DELETE,
AUTH
}

View File

@ -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()
}
}

View File

@ -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<SwitchPreference>(VectorPreferences.SETTINGS_ENCRYPTION_NEVER_SENT_TO_PREFERENCE_KEY)!!
}
private val openPinCodeSettingsPref by lazy {
findPreference<VectorPreference>("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<String> {
override fun onSuccess(data: String) {
findPreference<VectorPreference>(VectorPreferences.SETTINGS_CRYPTOGRAPHY_HS_ADMIN_DISABLED_E2E_DEFAULT)?.isVisible =
ElementWellKnownMapper.from(data)?.isE2EByDefault() == false
}
})
override fun onSuccess(data: String) {
findPreference<VectorPreference>(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

View File

@ -120,9 +120,8 @@
<im.vector.app.core.preference.VectorPreference
android:key="SETTINGS_SECURITY_PIN"
android:persistent="false"
android:title="@string/settings_security_application_protection_title"
android:summary="@string/settings_security_application_protection_summary"
app:fragment="im.vector.app.features.settings.VectorSettingsPinFragment" />
android:title="@string/settings_security_application_protection_title" />
<im.vector.app.core.preference.VectorSwitchPreference
android:defaultValue="false"