瀏覽代碼

Merge pull request #10518 from nextcloud/unsetEncryptionOnlyIfFolderEmpty

Only allow "unset encryption" when folder is empty
Álvaro Brey 2 年之前
父節點
當前提交
556a6bb0d5

+ 75 - 7
app/src/androidTest/java/com/owncloud/android/files/FileMenuFilterIT.kt

@@ -37,13 +37,17 @@ import com.owncloud.android.lib.resources.status.CapabilityBooleanType
 import com.owncloud.android.lib.resources.status.OCCapability
 import com.owncloud.android.services.OperationsService
 import com.owncloud.android.ui.activity.ComponentsGetter
+import com.owncloud.android.utils.MimeType
 import io.mockk.MockKAnnotations
 import io.mockk.every
 import io.mockk.impl.annotations.MockK
-import org.junit.Assert
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import java.security.SecureRandom
 
 @RunWith(AndroidJUnit4::class)
 class FileMenuFilterIT : AbstractIT() {
@@ -72,6 +76,7 @@ class FileMenuFilterIT : AbstractIT() {
         every { mockComponentsGetter.fileDownloaderBinder } returns mockFileDownloaderBinder
         every { mockOperationsServiceBinder.isSynchronizing(any(), any()) } returns false
         every { mockComponentsGetter.operationsServiceBinder } returns mockOperationsServiceBinder
+        every { mockStorageManager.getFileById(any()) } returns OCFile("/")
     }
 
     @Test
@@ -150,6 +155,69 @@ class FileMenuFilterIT : AbstractIT() {
         )
     }
 
+    @Test
+    fun filter_unset_encryption() {
+        val capability = OCCapability().apply {
+            endToEndEncryption = CapabilityBooleanType.TRUE
+        }
+
+        val encryptedFolder = OCFile("/encryptedFolder/").apply {
+            isEncrypted = true
+            mimeType = MimeType.DIRECTORY
+            fileLength = SecureRandom().nextLong()
+        }
+
+        val encryptedEmptyFolder = OCFile("/encryptedFolder/").apply {
+            isEncrypted = true
+            mimeType = MimeType.DIRECTORY
+        }
+
+        val normalFolder = OCFile("/folder/").apply {
+            mimeType = MimeType.DIRECTORY
+            fileLength = SecureRandom().nextLong()
+        }
+
+        val normalEmptyFolder = OCFile("/folder/").apply {
+            mimeType = MimeType.DIRECTORY
+        }
+
+        configureCapability(capability)
+
+        launchActivity<TestActivity>().use {
+            it.onActivity { activity ->
+                val menu = getMenu(activity)
+
+                var sut = FileMenuFilter(encryptedFolder, mockComponentsGetter, activity, true, user)
+                sut.filter(menu, false)
+
+                // encrypted folder, with content
+                assertFalse(menu.findItem(R.id.action_unset_encrypted).isVisible)
+                assertFalse(menu.findItem(R.id.action_encrypted).isVisible)
+
+                // encrypted, but empty folder
+                sut = FileMenuFilter(encryptedEmptyFolder, mockComponentsGetter, activity, true, user)
+                sut.filter(menu, false)
+
+                assertTrue(menu.findItem(R.id.action_unset_encrypted).isVisible)
+                assertFalse(menu.findItem(R.id.action_encrypted).isVisible)
+
+                // regular folder, with content
+                sut = FileMenuFilter(normalFolder, mockComponentsGetter, activity, true, user)
+                sut.filter(menu, false)
+
+                assertFalse(menu.findItem(R.id.action_unset_encrypted).isVisible)
+                assertFalse(menu.findItem(R.id.action_encrypted).isVisible)
+
+                // regular folder, without content
+                sut = FileMenuFilter(normalEmptyFolder, mockComponentsGetter, activity, true, user)
+                sut.filter(menu, false)
+
+                assertFalse(menu.findItem(R.id.action_unset_encrypted).isVisible)
+                assertTrue(menu.findItem(R.id.action_encrypted).isVisible)
+            }
+        }
+    }
+
     private data class ExpectedLockVisibilities(
         val lockFile: Boolean,
         val unlockFile: Boolean,
@@ -185,26 +253,26 @@ class FileMenuFilterIT : AbstractIT() {
 
                 sut.filter(menu, false)
 
-                Assert.assertEquals(
+                assertEquals(
                     expectedLockVisibilities.lockFile,
                     menu.findItem(R.id.action_lock_file).isVisible
                 )
-                Assert.assertEquals(
+                assertEquals(
                     expectedLockVisibilities.unlockFile,
                     menu.findItem(R.id.action_unlock_file).isVisible
                 )
-                Assert.assertEquals(
+                assertEquals(
                     expectedLockVisibilities.lockedBy,
                     menu.findItem(R.id.action_locked_by).isVisible
                 )
-                Assert.assertEquals(
+                assertEquals(
                     expectedLockVisibilities.lockedUntil,
                     menu.findItem(R.id.action_locked_until).isVisible
                 )
 
                 // locked by and until should always be disabled, they're not real actions
-                Assert.assertFalse(menu.findItem(R.id.action_locked_by).isEnabled)
-                Assert.assertFalse(menu.findItem(R.id.action_locked_until).isEnabled)
+                assertFalse(menu.findItem(R.id.action_locked_by).isEnabled)
+                assertFalse(menu.findItem(R.id.action_locked_until).isEnabled)
             }
         }
     }

+ 15 - 4
app/src/main/java/com/owncloud/android/files/FileMenuFilter.java

@@ -52,6 +52,7 @@ import java.util.List;
 public class FileMenuFilter {
 
     private static final int SINGLE_SELECT_ITEMS = 1;
+    private static final int EMPTY_FILE_LENGTH = 0;
     public static final String SEND_OFF = "off";
 
     private final int numberOfAllFiles;
@@ -234,7 +235,7 @@ public class FileMenuFilter {
 
     private void filterSendFiles(List<Integer> toShow, List<Integer> toHide, boolean inSingleFileFragment) {
         boolean show = true;
-        if (containsEncryptedFile() || overflowMenu || SEND_OFF.equalsIgnoreCase(context.getString(R.string.send_files_to_other_apps))) {
+        if (overflowMenu || SEND_OFF.equalsIgnoreCase(context.getString(R.string.send_files_to_other_apps)) || containsEncryptedFile()) {
             show = false;
         }
         if (!inSingleFileFragment && (isSingleSelection() || !anyFileDown())) {
@@ -312,7 +313,7 @@ public class FileMenuFilter {
 
     private void filterEncrypt(List<Integer> toShow, List<Integer> toHide, boolean endToEndEncryptionEnabled) {
         if (files.isEmpty() || !isSingleSelection() || isSingleFile() || isEncryptedFolder() || isGroupFolder()
-            || !endToEndEncryptionEnabled) {
+            || !endToEndEncryptionEnabled || !isEmptyFolder()) {
             toHide.add(R.id.action_encrypted);
         } else {
             toShow.add(R.id.action_encrypted);
@@ -320,8 +321,8 @@ public class FileMenuFilter {
     }
 
     private void filterUnsetEncrypted(List<Integer> toShow, List<Integer> toHide, boolean endToEndEncryptionEnabled) {
-        if (files.isEmpty() || !isSingleSelection() || isSingleFile() || !isEncryptedFolder() || hasEncryptedParent()
-            || !endToEndEncryptionEnabled) {
+        if (!endToEndEncryptionEnabled || files.isEmpty() || !isSingleSelection() || isSingleFile() || !isEncryptedFolder() || hasEncryptedParent()
+            || !isEmptyFolder()) {
             toHide.add(R.id.action_unset_encrypted);
         } else {
             toShow.add(R.id.action_unset_encrypted);
@@ -555,6 +556,16 @@ public class FileMenuFilter {
         }
     }
 
+    private boolean isEmptyFolder() {
+        if (isSingleSelection()) {
+            OCFile file = files.iterator().next();
+
+            return file.isFolder() && file.getFileLength() == EMPTY_FILE_LENGTH;
+        } else {
+            return false;
+        }
+    }
+
     private boolean isGroupFolder() {
         return files.iterator().next().isGroupFolder();
     }