diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultLocationController.java b/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultLocationController.java index 39e25d503..35f2be069 100644 --- a/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultLocationController.java +++ b/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultLocationController.java @@ -29,16 +29,20 @@ import javafx.scene.control.ToggleGroup; import javafx.stage.DirectoryChooser; import javafx.stage.Stage; import java.io.File; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; import java.util.ResourceBundle; +import java.util.UUID; @AddVaultWizardScoped public class CreateNewVaultLocationController implements FxController { private static final Logger LOG = LoggerFactory.getLogger(CreateNewVaultLocationController.class); private static final Path DEFAULT_CUSTOM_VAULT_PATH = Paths.get(System.getProperty("user.home")); + private static final String TEMP_FILE_FORMAT = "cryptomator-%s.tmp"; private final Stage window; private final Lazy chooseNameScene; @@ -92,7 +96,7 @@ public class CreateNewVaultLocationController implements FxController { statusText.set(resourceBundle.getString("addvaultwizard.new.locationDoesNotExist")); statusGraphic.set(badLocation); return false; - } else if (!Files.isWritable(p.getParent())) { + } else if (!isActuallyWritable(p.getParent())) { statusText.set(resourceBundle.getString("addvaultwizard.new.locationIsNotWritable")); statusGraphic.set(badLocation); return false; @@ -107,6 +111,21 @@ public class CreateNewVaultLocationController implements FxController { } } + private boolean isActuallyWritable(Path p) { + Path tmpFile = p.resolve(String.format(TEMP_FILE_FORMAT, UUID.randomUUID())); + try (var chan = Files.newByteChannel(tmpFile, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE, StandardOpenOption.DELETE_ON_CLOSE)) { + return true; + } catch (IOException e) { + return false; + } finally { + try { + Files.deleteIfExists(tmpFile); + } catch (IOException e) { + LOG.warn("Unable to delete temporary file {}. Needs to be deleted manually.", tmpFile); + } + } + } + @FXML public void initialize() { predefinedLocationToggler.selectedToggleProperty().addListener(this::togglePredefinedLocation);