mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-21 20:21:27 +00:00
Added implementations for MountPointChooser
Added AvailableDriveLetterChooser for automatic DriveLetter-choice Added CustomDriveLetterChooser for a chosen DriveLetter Added CustomMountPointChooser for a chosen directory Added TemporaryMountPointChooser for automatic directory-choice
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
package org.cryptomator.common.mountpoint;
|
||||
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.vaults.WindowsDriveLetters;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
|
||||
public class AvailableDriveLetterChooser implements MountPointChooser {
|
||||
|
||||
private final WindowsDriveLetters windowsDriveLetters;
|
||||
|
||||
public AvailableDriveLetterChooser(WindowsDriveLetters windowsDriveLetters) {
|
||||
this.windowsDriveLetters = windowsDriveLetters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable() {
|
||||
return SystemUtils.IS_OS_WINDOWS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Path> chooseMountPoint() {
|
||||
return this.windowsDriveLetters.getAvailableDriveLetterPath();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.cryptomator.common.mountpoint;
|
||||
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.settings.VaultSettings;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Optional;
|
||||
|
||||
public class CustomDriveLetterChooser implements MountPointChooser {
|
||||
|
||||
private final VaultSettings vaultSettings;
|
||||
|
||||
public CustomDriveLetterChooser(Vault vault) {
|
||||
this.vaultSettings = vault.getVaultSettings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable() {
|
||||
return SystemUtils.IS_OS_WINDOWS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Path> chooseMountPoint() {
|
||||
return this.vaultSettings.getWinDriveLetter().map(letter -> letter.charAt(0) + ":\\").map(Paths::get);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package org.cryptomator.common.mountpoint;
|
||||
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.settings.VaultSettings;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.DirectoryNotEmptyException;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.FileAlreadyExistsException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.LinkOption;
|
||||
import java.nio.file.NotDirectoryException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Optional;
|
||||
|
||||
public class CustomMountPointChooser implements MountPointChooser {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(CustomMountPointChooser.class);
|
||||
|
||||
private final VaultSettings vaultSettings;
|
||||
|
||||
public CustomMountPointChooser(Vault vault) {
|
||||
this.vaultSettings = vault.getVaultSettings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Path> chooseMountPoint() {
|
||||
//VaultSettings#getCustomMountPath already checks whether the saved custom mountpoint should be used
|
||||
return this.vaultSettings.getCustomMountPath().map(Paths::get);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean prepare(Path mountPoint) throws InvalidMountPointException {
|
||||
//On Windows the target folder MUST NOT exist...
|
||||
//https://github.com/billziss-gh/winfsp/issues/320
|
||||
if (SystemUtils.IS_OS_WINDOWS) {
|
||||
//We must use #notExists() here because notExists =/= !exists (see docs)
|
||||
if (Files.notExists(mountPoint, LinkOption.NOFOLLOW_LINKS)) {
|
||||
//File really doesn't exist
|
||||
return false;
|
||||
}
|
||||
//File exists OR can't be determined
|
||||
throw wrapAsIMPE(new FileAlreadyExistsException(mountPoint.toString()));
|
||||
}
|
||||
|
||||
//... on Mac and Linux it's the opposite
|
||||
if (!Files.isDirectory(mountPoint)) {
|
||||
throw wrapAsIMPE(new NotDirectoryException(mountPoint.toString()));
|
||||
}
|
||||
try (DirectoryStream<Path> ds = Files.newDirectoryStream(mountPoint)) {
|
||||
if (ds.iterator().hasNext()) {
|
||||
throw wrapAsIMPE(new DirectoryNotEmptyException(mountPoint.toString()));
|
||||
}
|
||||
} catch (IOException exception) {
|
||||
throw wrapAsIMPE(exception);
|
||||
}
|
||||
LOG.debug("Successfully checked custom mount point: {}", mountPoint);
|
||||
return false;
|
||||
}
|
||||
|
||||
private InvalidMountPointException wrapAsIMPE(Exception exception) {
|
||||
return new InvalidMountPointException(exception);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package org.cryptomator.common.mountpoint;
|
||||
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.Environment;
|
||||
import org.cryptomator.common.settings.VaultSettings;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Optional;
|
||||
|
||||
public class TemporaryMountPointChooser implements MountPointChooser {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TemporaryMountPointChooser.class);
|
||||
private static final int MAX_TMPMOUNTPOINT_CREATION_RETRIES = 10;
|
||||
|
||||
private final VaultSettings vaultSettings;
|
||||
private final Environment environment;
|
||||
|
||||
public TemporaryMountPointChooser(Vault vault, Environment environment) {
|
||||
this.vaultSettings = vault.getVaultSettings();
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable() {
|
||||
if(this.environment.getMountPointsDir().isEmpty()) {
|
||||
LOG.warn("\"cryptomator.mountPointsDir\" is not set to a valid path!");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Path> chooseMountPoint() {
|
||||
//Shouldn't throw, but let's keep #orElseThrow in case we made a mistake and the check in #isApplicable failed
|
||||
Path parent = this.environment.getMountPointsDir().orElseThrow();
|
||||
String basename = this.vaultSettings.getId();
|
||||
for (int i = 0; i < MAX_TMPMOUNTPOINT_CREATION_RETRIES; i++) {
|
||||
Path mountPoint = parent.resolve(basename + "_" + i);
|
||||
if (Files.notExists(mountPoint)) {
|
||||
return Optional.of(mountPoint);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean prepare(Path mountPoint) throws InvalidMountPointException {
|
||||
// https://github.com/osxfuse/osxfuse/issues/306#issuecomment-245114592:
|
||||
// In order to allow non-admin users to mount FUSE volumes in `/Volumes`,
|
||||
// starting with version 3.5.0, FUSE will create non-existent mount points automatically.
|
||||
if (SystemUtils.IS_OS_MAC && mountPoint.getParent().equals(Paths.get("/Volumes"))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
//WinFSP needs the parent, but the actual Mountpoint must not exist...
|
||||
if (SystemUtils.IS_OS_WINDOWS) {
|
||||
Files.createDirectories(mountPoint.getParent());
|
||||
return false;
|
||||
} else {
|
||||
//For Linux and Mac the actual Mountpoint must exist
|
||||
Files.createDirectories(mountPoint);
|
||||
return true;
|
||||
}
|
||||
} catch (IOException exception) {
|
||||
throw wrapAsIMPE(exception);
|
||||
}
|
||||
}
|
||||
|
||||
private InvalidMountPointException wrapAsIMPE(Exception exception) {
|
||||
return new InvalidMountPointException(exception);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user