Browse Source

Stopped user from mounting to vaults to the same path

JaniruTEC 2 years ago
parent
commit
9bb24320bf

+ 12 - 11
src/main/java/org/cryptomator/common/mount/MountWithinParentUtil.java

@@ -8,7 +8,6 @@ import java.io.IOException;
 import java.nio.file.FileAlreadyExistsException;
 import java.nio.file.Files;
 import java.nio.file.LinkOption;
-import java.nio.file.NoSuchFileException;
 import java.nio.file.Path;
 import java.nio.file.attribute.BasicFileAttributes;
 
@@ -23,7 +22,7 @@ public final class MountWithinParentUtil {
 
 	static void prepareParentNoMountPoint(Path mountPoint) throws IllegalMountPointException, IOException {
 		Path hideaway = getHideaway(mountPoint);
-		var mpExists = removeResidualJunction(mountPoint); //Handle junction as not existing
+		var mpExists = handleMountPointFolder(mountPoint); //Handle residual (= broken) junction as not existing
 		var hideExists = Files.exists(hideaway, LinkOption.NOFOLLOW_LINKS);
 
 		if (!mpExists && !hideExists) { //neither mountpoint nor hideaway exist
@@ -64,17 +63,19 @@ public final class MountWithinParentUtil {
 	}
 
 	//visible for testing
-	static boolean removeResidualJunction(Path path) throws IOException {
-		try {
-			if (Files.readAttributes(path, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS).isOther()) {
-				LOG.info("Mountpoint \"{}\" is still a junction. Deleting it.", path);
-				Files.delete(path); //Throws if path is also a non-empty folder
-				return false;
-			}
-			return true;
-		} catch (NoSuchFileException e) {
+	static boolean handleMountPointFolder(Path path) throws IOException {
+		if (Files.notExists(path, LinkOption.NOFOLLOW_LINKS)) {
 			return false;
 		}
+		if (!Files.readAttributes(path, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS).isOther()) {
+			return true;
+		}
+		if (Files.exists(path /* FOLLOW_LINKS */)) { //Both junction and target exist
+			throw new MountPointInUseException(path);
+		}
+		LOG.info("Mountpoint \"{}\" is still a junction. Deleting it.", path);
+		Files.delete(path); //Throws if path is also a non-empty folder
+		return false;
 	}
 
 	//visible for testing

+ 1 - 1
src/main/resources/i18n/strings.properties

@@ -130,7 +130,7 @@ unlock.success.revealBtn=Reveal Drive
 unlock.error.customPath.message=Unable to mount vault to custom path
 unlock.error.customPath.description.notSupported=If you wish to keep using the custom path, please go to the preferences and select a volume type that supports it. Otherwise, go to the vault options and choose a supported mount point.
 unlock.error.customPath.description.notExists=The custom mount path does not exist. Either create it in your local filesystem or change it in the vault options.
-unlock.error.customPath.description.inUse=Drive letter "%s" is already in use.
+unlock.error.customPath.description.inUse=The custom mount path "%s" is already in use.
 unlock.error.customPath.description.hideawayNotDir=The temporary, hidden file "%3$s" used for unlock could not be removed. Please check the file and then delete it manually.
 unlock.error.customPath.description.couldNotBeCleaned=Your vault could not be mounted to the path "%s". Please try again or choose a different path.
 unlock.error.customPath.description.notEmptyDir=The custom mount path "%s" is not an empty folder. Please choose an empty folder and try again.

+ 5 - 4
src/test/java/org/cryptomator/common/mount/MountWithinParentUtilTest.java

@@ -17,9 +17,9 @@ import java.util.Objects;
 import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
 import static org.cryptomator.common.mount.MountWithinParentUtil.cleanup;
 import static org.cryptomator.common.mount.MountWithinParentUtil.getHideaway;
+import static org.cryptomator.common.mount.MountWithinParentUtil.handleMountPointFolder;
 import static org.cryptomator.common.mount.MountWithinParentUtil.prepareParentNoMountPoint;
 import static org.cryptomator.common.mount.MountWithinParentUtil.removeResidualHideaway;
-import static org.cryptomator.common.mount.MountWithinParentUtil.removeResidualJunction;
 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -127,13 +127,14 @@ class MountWithinParentUtilTest {
 	}
 
 	@Test
-	void testRemoveResidualJunction(@TempDir Path parentDir) throws IOException {
+	void testHandleMountPointFolder(@TempDir Path parentDir) throws IOException {
 		//Sadly can't easily create files with "Other" attribute
 		var regularFile = parentDir.resolve("regularFile");
 		Files.createFile(regularFile);
 
-		assertTrue(removeResidualJunction(regularFile));
-		assertFalse(removeResidualJunction(parentDir.resolve("notExisting")));
+		assertTrue(handleMountPointFolder(regularFile));
+		assertTrue(Files.exists(regularFile));
+		assertFalse(handleMountPointFolder(parentDir.resolve("notExisting")));
 	}
 
 	@Test