From 4a58e621436094e67d51d3db174fb2769936ba51 Mon Sep 17 00:00:00 2001 From: Mihai Eduard Badea Date: Fri, 29 May 2020 15:00:38 +0300 Subject: [PATCH] [fenix] For issue https://github.com/mozilla-mobile/fenix/issues/10727 - Logins auth redirect Added an extension function that pops the backstack of the fragment so the user is redirected to the Logins and passwords screen. This is done to force the user to re-authenticate if he wants to re-enter the saved logins flow. Additionally, some UI elements are being hidden on each Fragment since they were remained visible on the Logins and passwords screen's UI. --- .../src/main/java/org/mozilla/fenix/ext/Fragment.kt | 17 +++++++++++++++++ .../fenix/settings/logins/EditLoginFragment.kt | 9 +++++++++ .../fenix/settings/logins/LoginDetailFragment.kt | 21 ++++++++++++++++++++- .../fenix/settings/logins/SavedLoginsFragment.kt | 7 ++----- 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt index e8e920b371bf..2b0a81d8609f 100644 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt @@ -12,7 +12,9 @@ import androidx.navigation.NavDirections import androidx.navigation.NavOptions import androidx.navigation.Navigator import androidx.navigation.fragment.NavHostFragment.findNavController +import androidx.navigation.fragment.findNavController import org.mozilla.fenix.HomeActivity +import org.mozilla.fenix.R import org.mozilla.fenix.components.Components /** @@ -51,3 +53,18 @@ fun Fragment.showToolbar(title: String) { fun Fragment.hideToolbar() { (requireActivity() as AppCompatActivity).supportActionBar?.hide() } + +/** + * Pops the backstack to force users to re-auth if they put the app in the background and return to it + * while being inside the saved logins flow + * It also updates the FLAG_SECURE status for the activity's window + * + * Does nothing if the user is currently navigating to any of the [destinations] given as a parameter + * + */ +fun Fragment.redirectToReAuth(destinations: List, currentDestination: Int?) { + if (currentDestination !in destinations) { + activity?.let { it.checkAndUpdateScreenshotPermission(it.settings()) } + findNavController().popBackStack(R.id.savedLoginsAuthFragment, false) + } +} diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/EditLoginFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/EditLoginFragment.kt index aa21d4f0be62..b4d2a0beba45 100644 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/EditLoginFragment.kt +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/EditLoginFragment.kt @@ -42,6 +42,7 @@ import org.mozilla.fenix.components.FenixSnackbar import org.mozilla.fenix.components.StoreProvider import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.ext.components +import org.mozilla.fenix.ext.redirectToReAuth import org.mozilla.fenix.ext.settings /** @@ -114,6 +115,14 @@ class EditLoginFragment : Fragment(R.layout.fragment_edit_login) { inflater.inflate(R.menu.login_save, menu) } + override fun onPause() { + redirectToReAuth( + listOf(R.id.loginDetailFragment), + findNavController().currentDestination?.id + ) + super.onPause() + } + override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) { R.id.save_login_button -> { view?.hideKeyboard() diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/LoginDetailFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/LoginDetailFragment.kt index ae2f6cfaa3be..c63db284f18e 100644 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/LoginDetailFragment.kt +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/LoginDetailFragment.kt @@ -38,6 +38,7 @@ import org.mozilla.fenix.components.FenixSnackbar import org.mozilla.fenix.components.StoreProvider import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.ext.components +import org.mozilla.fenix.ext.redirectToReAuth import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.ext.urlToTrimmedHost @@ -53,6 +54,8 @@ class LoginDetailFragment : Fragment(R.layout.fragment_login_detail) { private var login: SavedLogin? = null private lateinit var savedLoginsStore: LoginsFragmentStore private lateinit var loginDetailView: LoginDetailView + private lateinit var menu: Menu + private var deleteDialog: AlertDialog? = null override fun onCreateView( inflater: LayoutInflater, @@ -98,6 +101,21 @@ class LoginDetailFragment : Fragment(R.layout.fragment_login_detail) { setHasOptionsMenu(true) } + /** + * As described in #10727, the User should re-auth if the fragment is paused and the user is not + * navigating to SavedLoginsFragment or EditLoginFragment + * + */ + override fun onPause() { + deleteDialog?.isShowing.run { deleteDialog?.dismiss() } + menu.close() + redirectToReAuth( + listOf(R.id.editLoginFragment, R.id.savedLoginsFragment), + findNavController().currentDestination?.id + ) + super.onPause() + } + private fun setUpPasswordReveal() { passwordText.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD @@ -156,6 +174,7 @@ class LoginDetailFragment : Fragment(R.layout.fragment_login_detail) { } else { inflater.inflate(R.menu.login_delete, menu) } + this.menu = menu } override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) { @@ -179,7 +198,7 @@ class LoginDetailFragment : Fragment(R.layout.fragment_login_detail) { private fun displayDeleteLoginDialog() { activity?.let { activity -> - AlertDialog.Builder(activity).apply { + deleteDialog = AlertDialog.Builder(activity).apply { setMessage(R.string.login_deletion_confirmation) setNegativeButton(android.R.string.cancel) { dialog: DialogInterface, _ -> dialog.cancel() diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/SavedLoginsFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/SavedLoginsFragment.kt index eebd97824afb..e76800c6fb62 100644 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/SavedLoginsFragment.kt +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/SavedLoginsFragment.kt @@ -38,8 +38,8 @@ import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.components.StoreProvider import org.mozilla.fenix.components.metrics.Event -import org.mozilla.fenix.ext.checkAndUpdateScreenshotPermission import org.mozilla.fenix.ext.components +import org.mozilla.fenix.ext.redirectToReAuth import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.settings.SupportUtils @@ -134,10 +134,7 @@ class SavedLoginsFragment : Fragment() { (activity as HomeActivity).getSupportActionBarAndInflateIfNecessary().setDisplayShowTitleEnabled(true) sortingStrategyPopupMenu.dismiss() - if (findNavController().currentDestination?.id != R.id.loginDetailFragment) { - activity?.let { it.checkAndUpdateScreenshotPermission(it.settings()) } - findNavController().popBackStack(R.id.savedLoginsAuthFragment, false) - } + redirectToReAuth(listOf(R.id.loginDetailFragment), findNavController().currentDestination?.id) super.onPause() } -- 2.11.4.GIT