Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 12 additions & 11 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ Summary
* Bugfix - Small bug when privacy policy disabled: [#3542](https://github.com/owncloud/android/pull/3542)
* Enhancement - Permission dialog removal: [#2524](https://github.com/owncloud/android/pull/2524)
* Enhancement - Lock delay for app: [#3344](https://github.com/owncloud/android/issues/3344)
* Enhancement - Allow access from document provider preference: [#3379](https://github.com/owncloud/android/issues/3379)
* Enhancement - Security enforced: [#3434](https://github.com/owncloud/android/pull/3434)
* Enhancement - Respect capability for Avatar support: [#3438](https://github.com/owncloud/android/pull/3438)
* Enhancement - Brute force protection: [#3320](https://github.com/owncloud/android/issues/3320)
* Enhancement - "Open with" action now allows editing: [#3475](https://github.com/owncloud/android/issues/3475)
* Enhancement - Enable logs by default in debug mode: [#3526](https://github.com/owncloud/android/issues/3526)
* Enhancement - Allow access from document provider preference: [#3379](https://github.com/owncloud/android/issues/3379)
* Enhancement - Suggest the user to enable enhanced security: [#3539](https://github.com/owncloud/android/pull/3539)

Details
Expand Down Expand Up @@ -55,16 +55,6 @@ Details
https://github.com/owncloud/android/issues/3344
https://github.com/owncloud/android/pull/3375

* Enhancement - Allow access from document provider preference: [#3379](https://github.com/owncloud/android/issues/3379)

Previously, files of ownCloud accounts couldn't be accessed from document provider or
Android native file explorer when there was a lock set in the app. Now, a new preference has been
added to allow the access when the app is locked, disabled by default so that it's safer for those
who don't want this feature.

https://github.com/owncloud/android/issues/3379
https://github.com/owncloud/android/pull/3384

* Enhancement - Security enforced: [#3434](https://github.com/owncloud/android/pull/3434)

A new branding/MDM option has been added to make app lock via passcode or pattern compulsory,
Expand Down Expand Up @@ -107,6 +97,17 @@ Details
https://github.com/owncloud/android/issues/3526
https://github.com/owncloud/android/pull/3527

* Enhancement - Allow access from document provider preference: [#3379](https://github.com/owncloud/android/issues/3379)

Previously, files of ownCloud accounts couldn't be accessed via documents provider when
there was a lock set in the app. Now, a new preference has been added to allow/disallow the
access, so users have more control over their files.

https://github.com/owncloud/android/issues/3379
https://github.com/owncloud/android/issues/3520
https://github.com/owncloud/android/pull/3384
https://github.com/owncloud/android/pull/3538

* Enhancement - Suggest the user to enable enhanced security: [#3539](https://github.com/owncloud/android/pull/3539)

When a user sets the passcode or pattern lock on the security screen, the application suggests
Expand Down
10 changes: 0 additions & 10 deletions changelog/unreleased/3384

This file was deleted.

10 changes: 10 additions & 0 deletions changelog/unreleased/3538
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Enhancement: Allow access from document provider preference

Previously, files of ownCloud accounts couldn't be accessed via documents provider
when there was a lock set in the app. Now, a new preference has been
added to allow/disallow the access, so users have more control over their files.

https://github.com/owncloud/android/issues/3379
https://github.com/owncloud/android/issues/3520
https://github.com/owncloud/android/pull/3384
https://github.com/owncloud/android/pull/3538
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import com.owncloud.android.presentation.ui.security.PREFERENCE_LOCK_TIMEOUT
import com.owncloud.android.presentation.ui.security.PassCodeActivity
import com.owncloud.android.presentation.ui.security.PatternActivity
import com.owncloud.android.presentation.ui.settings.fragments.SettingsSecurityFragment
import com.owncloud.android.presentation.ui.settings.fragments.SettingsSecurityFragment.Companion.PREFERENCE_ACCESS_FROM_DOCUMENT_PROVIDER
import com.owncloud.android.presentation.ui.settings.fragments.SettingsSecurityFragment.Companion.PREFERENCE_LOCK_ACCESS_FROM_DOCUMENT_PROVIDER
import com.owncloud.android.presentation.viewmodels.settings.SettingsSecurityViewModel
import com.owncloud.android.testutil.security.OC_PATTERN
import com.owncloud.android.utils.matchers.verifyPreference
Expand Down Expand Up @@ -74,7 +74,7 @@ class SettingsSecurityFragmentTest {
private lateinit var prefPattern: CheckBoxPreference
private var prefBiometric: CheckBoxPreference? = null
private lateinit var prefLockApplication: ListPreference
private lateinit var prefAccessDocumentProvider: CheckBoxPreference
private lateinit var prefLockAccessDocumentProvider: CheckBoxPreference
private lateinit var prefTouchesWithOtherVisibleWindows: CheckBoxPreference

private lateinit var securityViewModel: SettingsSecurityViewModel
Expand Down Expand Up @@ -121,7 +121,7 @@ class SettingsSecurityFragmentTest {
prefPattern = fragment.findPreference(PatternActivity.PREFERENCE_SET_PATTERN)!!
prefBiometric = fragment.findPreference(BiometricActivity.PREFERENCE_SET_BIOMETRIC)
prefLockApplication = fragment.findPreference(PREFERENCE_LOCK_TIMEOUT)!!
prefAccessDocumentProvider = fragment.findPreference(PREFERENCE_ACCESS_FROM_DOCUMENT_PROVIDER)!!
prefLockAccessDocumentProvider = fragment.findPreference(PREFERENCE_LOCK_ACCESS_FROM_DOCUMENT_PROVIDER)!!
prefTouchesWithOtherVisibleWindows =
fragment.findPreference(SettingsSecurityFragment.PREFERENCE_TOUCHES_WITH_OTHER_VISIBLE_WINDOWS)!!
}
Expand Down Expand Up @@ -151,14 +151,14 @@ class SettingsSecurityFragmentTest {
enabled = false
)

prefAccessDocumentProvider.verifyPreference(
keyPref = PREFERENCE_ACCESS_FROM_DOCUMENT_PROVIDER,
titlePref = context.getString(R.string.prefs_access_from_document_provider),
summaryPref = context.getString(R.string.prefs_access_from_document_provider_summary),
prefLockAccessDocumentProvider.verifyPreference(
keyPref = PREFERENCE_LOCK_ACCESS_FROM_DOCUMENT_PROVIDER,
titlePref = context.getString(R.string.prefs_lock_access_from_document_provider),
summaryPref = context.getString(R.string.prefs_lock_access_from_document_provider_summary),
visible = true,
enabled = false
enabled = true
)
assertFalse(prefAccessDocumentProvider.isChecked)
assertFalse(prefLockAccessDocumentProvider.isChecked)

prefTouchesWithOtherVisibleWindows.verifyPreference(
keyPref = SettingsSecurityFragment.PREFERENCE_TOUCHES_WITH_OTHER_VISIBLE_WINDOWS,
Expand Down Expand Up @@ -247,29 +247,25 @@ class SettingsSecurityFragmentTest {
}

@Test
fun enablePasscodeEnablesBiometricLockAndLockApplicationAndAccessFromDocumentProvider() {
fun enablePasscodeEnablesBiometricLockAndLockApplication() {
launchTest()

firstEnablePasscode()
onView(withText(R.string.prefs_biometric)).check(matches(isEnabled()))
assertTrue(prefBiometric!!.isEnabled)
assertFalse(prefBiometric!!.isChecked)
assertTrue(prefLockApplication.isEnabled)
assertTrue(prefAccessDocumentProvider.isEnabled)
assertFalse(prefAccessDocumentProvider.isChecked)
}

@Test
fun enablePatternEnablesBiometricLockAndLockApplicationAndAccessFromDocumentProvider() {
fun enablePatternEnablesBiometricLockAndLockApplication() {
launchTest()

firstEnablePattern()
onView(withText(R.string.prefs_biometric)).check(matches(isEnabled()))
assertTrue(prefBiometric!!.isEnabled)
assertFalse(prefBiometric!!.isChecked)
assertTrue(prefLockApplication.isEnabled)
assertTrue(prefAccessDocumentProvider.isEnabled)
assertFalse(prefAccessDocumentProvider.isChecked)
}

@Test
Expand Down Expand Up @@ -308,8 +304,6 @@ class SettingsSecurityFragmentTest {
assertFalse(prefBiometric!!.isEnabled)
assertFalse(prefBiometric!!.isChecked)
assertFalse(prefLockApplication.isEnabled)
assertFalse(prefAccessDocumentProvider.isEnabled)
assertFalse(prefAccessDocumentProvider.isChecked)
}

@Test
Expand All @@ -326,8 +320,6 @@ class SettingsSecurityFragmentTest {
assertFalse(prefBiometric!!.isEnabled)
assertFalse(prefBiometric!!.isChecked)
assertFalse(prefLockApplication.isEnabled)
assertFalse(prefAccessDocumentProvider.isEnabled)
assertFalse(prefAccessDocumentProvider.isChecked)
}

@Test
Expand Down Expand Up @@ -377,44 +369,20 @@ class SettingsSecurityFragmentTest {
}

@Test
fun accessFromDocumentProviderDialog() {
launchTest()

firstEnablePasscode()
onView(withText(R.string.prefs_access_from_document_provider)).perform(click())
onView(withText(R.string.confirmation_access_from_document_provider_title)).check(matches(isDisplayed()))
onView(withText(R.string.confirmation_access_from_document_provider_message)).check(matches(isDisplayed()))
}

@Test
fun accessFromDocumentProviderEnable() {
fun lockAccessFromDocumentProviderEnable() {
launchTest()

firstEnablePasscode()
onView(withText(R.string.prefs_access_from_document_provider)).perform(click())
onView(withText(R.string.common_yes)).perform(click())
assertTrue(prefAccessDocumentProvider.isChecked)
onView(withText(R.string.prefs_lock_access_from_document_provider)).perform(click())
assertTrue(prefLockAccessDocumentProvider.isChecked)
}

@Test
fun accessFromDocumentProviderRefuse() {
fun lockAccessFromDocumentProviderDisable() {
launchTest()

firstEnablePasscode()
onView(withText(R.string.prefs_access_from_document_provider)).perform(click())
onView(withText(R.string.common_no)).perform(click())
assertFalse(prefAccessDocumentProvider.isChecked)
}

@Test
fun accessFromDocumentProviderDisable() {
launchTest()

firstEnablePasscode()
onView(withText(R.string.prefs_access_from_document_provider)).perform(click())
onView(withText(R.string.common_yes)).perform(click())
onView(withText(R.string.prefs_access_from_document_provider)).perform(click())
assertFalse(prefAccessDocumentProvider.isChecked)
onView(withText(R.string.prefs_lock_access_from_document_provider)).perform(click())
onView(withText(R.string.prefs_lock_access_from_document_provider)).perform(click())
assertFalse(prefLockAccessDocumentProvider.isChecked)
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* @author Juan Carlos Garrote Gascón
*
* Copyright (C) 2021 ownCloud GmbH.
* Copyright (C) 2022 ownCloud GmbH.
* <p>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
Expand Down Expand Up @@ -54,7 +54,7 @@ class SettingsSecurityFragment : PreferenceFragmentCompat() {
private var prefPattern: CheckBoxPreference? = null
private var prefBiometric: CheckBoxPreference? = null
private var prefLockApplication: ListPreference? = null
private var prefAccessDocumentProvider: CheckBoxPreference? = null
private var prefLockAccessDocumentProvider: CheckBoxPreference? = null
private var prefTouchesWithOtherVisibleWindows: CheckBoxPreference? = null

private val enablePasscodeLauncher =
Expand All @@ -65,7 +65,7 @@ class SettingsSecurityFragment : PreferenceFragmentCompat() {
prefBiometric?.isChecked = securityViewModel.getBiometricsState()

// Allow to use biometric lock, lock delay and access from document provider since Passcode lock has been enabled
enableBiometricAndLockApplicationAndAccessFromDocumentProvider()
enableBiometricAndLockApplication()
}
}

Expand All @@ -78,7 +78,6 @@ class SettingsSecurityFragment : PreferenceFragmentCompat() {
// Do not allow to use biometric lock, lock delay nor access from document provider since Passcode lock has been disabled
disableBiometric()
prefLockApplication?.isEnabled = false
disableAccessFromDocumentProvider()
}
}

Expand All @@ -90,7 +89,7 @@ class SettingsSecurityFragment : PreferenceFragmentCompat() {
prefBiometric?.isChecked = securityViewModel.getBiometricsState()

// Allow to use biometric lock, lock delay and access from document provider since Pattern lock has been enabled
enableBiometricAndLockApplicationAndAccessFromDocumentProvider()
enableBiometricAndLockApplication()
}
}

Expand All @@ -103,7 +102,6 @@ class SettingsSecurityFragment : PreferenceFragmentCompat() {
// Do not allow to use biometric lock, lock delay nor access from document provider since Pattern lock has been disabled
disableBiometric()
prefLockApplication?.isEnabled = false
disableAccessFromDocumentProvider()
}
}

Expand All @@ -128,7 +126,7 @@ class SettingsSecurityFragment : PreferenceFragmentCompat() {
LockTimeout.THIRTY_MINUTES.name
).toTypedArray()
}
prefAccessDocumentProvider = findPreference(PREFERENCE_ACCESS_FROM_DOCUMENT_PROVIDER)
prefLockAccessDocumentProvider = findPreference(PREFERENCE_LOCK_ACCESS_FROM_DOCUMENT_PROVIDER)
prefTouchesWithOtherVisibleWindows = findPreference(PREFERENCE_TOUCHES_WITH_OTHER_VISIBLE_WINDOWS)

prefPasscode?.isVisible = !securityViewModel.isSecurityEnforcedEnabled()
Expand All @@ -152,7 +150,7 @@ class SettingsSecurityFragment : PreferenceFragmentCompat() {
}

// Pattern lock
prefPattern?.setOnPreferenceChangeListener { preference: Preference?, newValue: Any ->
prefPattern?.setOnPreferenceChangeListener { _: Preference?, newValue: Any ->
Comment thread
JuancaG05 marked this conversation as resolved.
if (securityViewModel.isPasscodeSet()) {
showMessageInSnackbar(getString(R.string.passcode_already_set))
} else {
Expand All @@ -179,7 +177,7 @@ class SettingsSecurityFragment : PreferenceFragmentCompat() {
disableBiometric()
}

prefBiometric?.setOnPreferenceChangeListener { preference: Preference?, newValue: Any ->
prefBiometric?.setOnPreferenceChangeListener { _: Preference?, newValue: Any ->
val incomingValue = newValue as Boolean

// No biometric enrolled yet
Expand All @@ -192,37 +190,20 @@ class SettingsSecurityFragment : PreferenceFragmentCompat() {
}
}

// Lock application and Access from document provider visibility
// Lock application
if (prefPasscode?.isChecked == false && prefPattern?.isChecked == false) {
prefLockApplication?.isEnabled = false
disableAccessFromDocumentProvider()
}

// Access from document provider
prefAccessDocumentProvider?.setOnPreferenceChangeListener { preference: Preference?, newValue: Any ->
if (newValue as Boolean) {
activity?.let {
AlertDialog.Builder(it)
.setTitle(getString(R.string.confirmation_access_from_document_provider_title))
.setMessage(getString(R.string.confirmation_access_from_document_provider_message))
.setNegativeButton(getString(R.string.common_no), null)
.setPositiveButton(
getString(R.string.common_yes)
) { dialog: DialogInterface?, which: Int ->
securityViewModel.setPrefAccessDocumentProvider(true)
prefAccessDocumentProvider?.isChecked = true
notifyDocumentProviderRoots(requireContext())
}
.show()
}
return@setOnPreferenceChangeListener false
}
// Lock access from document provider
prefLockAccessDocumentProvider?.setOnPreferenceChangeListener { _: Preference?, newValue: Any ->
securityViewModel.setPrefLockAccessDocumentProvider(true)
notifyDocumentProviderRoots(requireContext())
true
}

// Touches with other visible windows
prefTouchesWithOtherVisibleWindows?.setOnPreferenceChangeListener { preference: Preference?, newValue: Any ->
prefTouchesWithOtherVisibleWindows?.setOnPreferenceChangeListener { _: Preference?, newValue: Any ->
if (newValue as Boolean) {
activity?.let {
AlertDialog.Builder(it)
Expand All @@ -231,7 +212,7 @@ class SettingsSecurityFragment : PreferenceFragmentCompat() {
.setNegativeButton(getString(R.string.common_no), null)
.setPositiveButton(
getString(R.string.common_yes)
) { dialog: DialogInterface?, which: Int ->
) { _: DialogInterface?, _: Int ->
securityViewModel.setPrefTouchesWithOtherVisibleWindows(true)
prefTouchesWithOtherVisibleWindows?.isChecked = true
}
Expand All @@ -243,13 +224,12 @@ class SettingsSecurityFragment : PreferenceFragmentCompat() {
}
}

private fun enableBiometricAndLockApplicationAndAccessFromDocumentProvider() {
private fun enableBiometricAndLockApplication() {
prefBiometric?.apply {
isEnabled = true
summary = null
}
prefLockApplication?.isEnabled = true
prefAccessDocumentProvider?.isEnabled = true
}

private fun disableBiometric() {
Expand All @@ -260,16 +240,9 @@ class SettingsSecurityFragment : PreferenceFragmentCompat() {
}
}

private fun disableAccessFromDocumentProvider() {
prefAccessDocumentProvider?.apply {
isChecked = false
isEnabled = false
}
}

companion object {
private const val SCREEN_SECURITY = "security_screen"
const val PREFERENCE_ACCESS_FROM_DOCUMENT_PROVIDER = "access_from_document_provider"
const val PREFERENCE_LOCK_ACCESS_FROM_DOCUMENT_PROVIDER = "lock_access_from_document_provider"
const val PREFERENCE_TOUCHES_WITH_OTHER_VISIBLE_WINDOWS = "touches_with_other_visible_windows"
const val EXTRAS_LOCK_ENFORCED = "EXTRAS_LOCK_ENFORCED"
const val PREFERENCE_LOCK_ATTEMPTS = "PrefLockAttempts"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ class SettingsSecurityViewModel(

fun isPasscodeSet() = preferencesProvider.getBoolean(PassCodeActivity.PREFERENCE_SET_PASSCODE, false)

fun setPrefAccessDocumentProvider(value: Boolean) =
preferencesProvider.putBoolean(SettingsSecurityFragment.PREFERENCE_ACCESS_FROM_DOCUMENT_PROVIDER, value)
fun setPrefLockAccessDocumentProvider(value: Boolean) =
preferencesProvider.putBoolean(SettingsSecurityFragment.PREFERENCE_LOCK_ACCESS_FROM_DOCUMENT_PROVIDER, value)

fun setPrefTouchesWithOtherVisibleWindows(value: Boolean) =
preferencesProvider.putBoolean(SettingsSecurityFragment.PREFERENCE_TOUCHES_WITH_OTHER_VISIBLE_WINDOWS, value)
Expand Down
Loading