Merge pull request #18094 from iterate-ch/feature/preflight-argument-optionals

Review preflight parameters
This commit is contained in:
Yves Langisch
2026-05-09 14:36:50 +02:00
committed by GitHub
71 changed files with 310 additions and 241 deletions
@@ -32,6 +32,7 @@ import org.apache.commons.lang3.StringUtils;
import java.text.MessageFormat;
import java.util.EnumSet;
import java.util.Optional;
import com.azure.core.exception.HttpResponseException;
@@ -69,28 +70,28 @@ public class AzureDirectoryFeature implements Directory<Void> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(workdir.isRoot()) {
if(!validate(filename)) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename));
if(filename.isPresent()) {
if(!validate(filename.get())) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename));
}
}
// Empty argument if not known in validation
}
}
public static boolean validate(final String filename) {
// Empty argument if not known in validation
if(StringUtils.isNotBlank(filename)) {
// Container names must be lowercase, between 3-63 characters long and must start with a letter or
// number. Container names may contain only letters, numbers, and the dash (-) character.
if(StringUtils.length(filename) > 63) {
return false;
}
if(StringUtils.length(filename) < 3) {
return false;
}
if(!StringUtils.isAlphanumeric(RegExUtils.removeAll(filename, "-"))) {
return false;
}
// Container names must be lowercase, between 3-63 characters long and must start with a letter or
// number. Container names may contain only letters, numbers, and the dash (-) character.
if(StringUtils.length(filename) > 63) {
return false;
}
if(StringUtils.length(filename) < 3) {
return false;
}
if(!StringUtils.isAlphanumeric(RegExUtils.removeAll(filename, "-"))) {
return false;
}
return true;
}
@@ -26,6 +26,7 @@ import ch.cyberduck.core.transfer.TransferStatus;
import org.apache.commons.io.input.NullInputStream;
import java.text.MessageFormat;
import java.util.Optional;
public class AzureTouchFeature extends DefaultTouchFeature<Void> {
@@ -34,7 +35,7 @@ public class AzureTouchFeature extends DefaultTouchFeature<Void> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(workdir.isRoot()) {
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename)).withFile(workdir);
}
@@ -16,6 +16,7 @@ import org.junit.experimental.categories.Category;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Optional;
import static org.junit.Assert.*;
@@ -38,8 +39,8 @@ public class AzureDirectoryFeatureTest extends AbstractAzureTest {
public void testCreateContainerInvalidName() throws Exception {
final Path container = new Path("untitled folder", EnumSet.of(Path.Type.directory));
final AzureDirectoryFeature feature = new AzureDirectoryFeature(session);
assertFalse(feature.isSupported(container.getParent(), container.getName()));
assertThrows(InvalidFilenameException.class, () -> feature.preflight(container.getParent(), container.getName()));
assertFalse(feature.isSupported(container.getParent(), Optional.of(container.getName())));
assertThrows(InvalidFilenameException.class, () -> feature.preflight(container.getParent(), Optional.of(container.getName())));
feature.mkdir(new AzureWriteFeature(session), container, new TransferStatus());
assertTrue(new AzureFindFeature(session).find(container));
new AzureDeleteFeature(session).delete(Collections.singletonList(container), LoginCallback.noop, new Delete.DisabledCallback());
@@ -28,6 +28,7 @@ import org.junit.experimental.categories.Category;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Optional;
@Category(IntegrationTest.class)
public class AzureTouchFeatureTest extends AbstractAzureTest {
@@ -44,9 +45,9 @@ public class AzureTouchFeatureTest extends AbstractAzureTest {
public void testPreflightFilename() throws Exception {
final Path container = new Path("cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume));
final AzureTouchFeature feature = new AzureTouchFeature(session);
feature.preflight(container, new AsciiRandomStringService().random());
feature.preflight(container, new AlphanumericRandomStringService().random());
feature.preflight(container, String.format("%s.suffix", new AlphanumericRandomStringService().random()));
feature.preflight(container, "?");
feature.preflight(container, Optional.of(new AsciiRandomStringService().random()));
feature.preflight(container, Optional.of(new AlphanumericRandomStringService().random()));
feature.preflight(container, Optional.of(String.format("%s.suffix", new AlphanumericRandomStringService().random())));
feature.preflight(container, Optional.of("?"));
}
}
@@ -33,6 +33,7 @@ import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.EnumSet;
import java.util.Optional;
import synapticloop.b2.BucketType;
import synapticloop.b2.exception.B2ApiException;
@@ -79,23 +80,23 @@ public class B2DirectoryFeature implements Directory<BaseB2Response> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(workdir.isRoot()) {
// Empty argument if not known in validation
if(StringUtils.isNotBlank(filename)) {
if(filename.isPresent()) {
// Bucket names must be a minimum of 6 and a maximum of 50 characters long, and must be globally unique;
// two different B2 accounts cannot have buckets with the name name. Bucket names can consist of: letters,
// digits, and "-". Bucket names cannot start with "b2-"; these are reserved for internal Backblaze use.
if(StringUtils.startsWith(filename, "b2-")) {
if(StringUtils.startsWith(filename.get(), "b2-")) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename));
}
if(StringUtils.length(filename) > 50) {
if(StringUtils.length(filename.get()) > 50) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename));
}
if(StringUtils.length(filename) < 6) {
if(StringUtils.length(filename.get()) < 6) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename));
}
if(!StringUtils.isAlphanumeric(RegExUtils.removeAll(filename, "-"))) {
if(!StringUtils.isAlphanumeric(RegExUtils.removeAll(filename.get(), "-"))) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename));
}
}
@@ -26,6 +26,7 @@ import ch.cyberduck.core.transfer.TransferStatus;
import org.apache.commons.io.input.NullInputStream;
import java.text.MessageFormat;
import java.util.Optional;
import synapticloop.b2.response.BaseB2Response;
@@ -41,7 +42,7 @@ public class B2TouchFeature extends DefaultTouchFeature<BaseB2Response> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
// Creating files is only possible inside a bucket.
if(workdir.isRoot()) {
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename)).withFile(workdir);
@@ -31,6 +31,7 @@ import org.junit.experimental.categories.Category;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Optional;
import static org.junit.Assert.*;
@@ -42,7 +43,7 @@ public class B2DirectoryFeatureTest extends AbstractB2Test {
final Path bucket = new Path(new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory, Path.Type.volume));
final B2VersionIdProvider fileid = new B2VersionIdProvider(session);
final B2DirectoryFeature feature = new B2DirectoryFeature(session, fileid);
assertTrue(feature.isSupported(bucket.getParent(), bucket.getName()));
assertTrue(feature.isSupported(bucket.getParent(), Optional.of(bucket.getName())));
feature.mkdir(new B2WriteFeature(session, fileid), bucket, new TransferStatus());
assertThrows(ConflictException.class, () -> feature.mkdir(new B2WriteFeature(session, fileid), bucket, new TransferStatus()));
new B2DeleteFeature(session, fileid).delete(Collections.singletonList(bucket), LoginCallback.noop, new Delete.DisabledCallback());
@@ -65,7 +66,7 @@ public class B2DirectoryFeatureTest extends AbstractB2Test {
public void testBucketInvalidCharacter() throws Exception {
final Path bucket = new Path("untitled folder", EnumSet.of(Path.Type.directory, Path.Type.volume));
final B2VersionIdProvider fileid = new B2VersionIdProvider(session);
assertFalse(new B2DirectoryFeature(session, fileid).isSupported(bucket.getParent(), bucket.getName()));
assertFalse(new B2DirectoryFeature(session, fileid).isSupported(bucket.getParent(), Optional.of(bucket.getName())));
try {
new B2DirectoryFeature(session, fileid).mkdir(new B2WriteFeature(session, fileid), bucket, new TransferStatus());
}
@@ -30,6 +30,7 @@ import ch.cyberduck.core.transfer.TransferStatus;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.Optional;
public class BoxDirectoryFeature implements Directory<File> {
@@ -55,9 +56,11 @@ public class BoxDirectoryFeature implements Directory<File> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
if(!BoxTouchFeature.validate(filename)) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename));
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(filename.isPresent()) {
if(!BoxTouchFeature.validate(filename.get())) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename));
}
}
}
}
@@ -25,6 +25,7 @@ import ch.cyberduck.core.shared.DefaultTouchFeature;
import org.apache.commons.lang3.StringUtils;
import java.text.MessageFormat;
import java.util.Optional;
public class BoxTouchFeature extends DefaultTouchFeature<File> {
@@ -33,9 +34,11 @@ public class BoxTouchFeature extends DefaultTouchFeature<File> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
if(!validate(filename)) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename));
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(filename.isPresent()) {
if(!validate(filename.get())) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename));
}
}
}
@@ -30,6 +30,7 @@ import org.junit.experimental.categories.Category;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Optional;
import static org.junit.Assert.*;
@@ -53,11 +54,11 @@ public class BoxDirectoryFeatureTest extends AbstractBoxTest {
@Test
public void isSupported() {
final BoxFileidProvider fileid = new BoxFileidProvider(session);
assertTrue(new BoxDirectoryFeature(session, fileid).isSupported(Home.root(), new AlphanumericRandomStringService().random()));
assertFalse(new BoxDirectoryFeature(session, fileid).isSupported(Home.root(), String.format("%s ", new AlphanumericRandomStringService().random())));
assertFalse(new BoxDirectoryFeature(session, fileid).isSupported(Home.root(), String.format("%s\\", new AlphanumericRandomStringService().random())));
assertFalse(new BoxDirectoryFeature(session, fileid).isSupported(Home.root(), String.format("%s/", new AlphanumericRandomStringService().random())));
assertFalse(new BoxDirectoryFeature(session, fileid).isSupported(Home.root(), "."));
assertFalse(new BoxDirectoryFeature(session, fileid).isSupported(Home.root(), ".."));
assertTrue(new BoxDirectoryFeature(session, fileid).isSupported(Home.root(), Optional.of(new AlphanumericRandomStringService().random())));
assertFalse(new BoxDirectoryFeature(session, fileid).isSupported(Home.root(), Optional.of(String.format("%s ", new AlphanumericRandomStringService().random()))));
assertFalse(new BoxDirectoryFeature(session, fileid).isSupported(Home.root(), Optional.of(String.format("%s\\", new AlphanumericRandomStringService().random()))));
assertFalse(new BoxDirectoryFeature(session, fileid).isSupported(Home.root(), Optional.of(String.format("%s/", new AlphanumericRandomStringService().random()))));
assertFalse(new BoxDirectoryFeature(session, fileid).isSupported(Home.root(), Optional.of(".")));
assertFalse(new BoxDirectoryFeature(session, fileid).isSupported(Home.root(), Optional.of("..")));
}
}
@@ -21,6 +21,8 @@ import ch.cyberduck.test.IntegrationTest;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import java.util.Optional;
import static org.junit.Assert.assertTrue;
@Category(IntegrationTest.class)
@@ -29,6 +31,6 @@ public class BoxTouchFeatureTest extends AbstractBoxTest {
@Test
public void testSupported() {
final BoxFileidProvider fileid = new BoxFileidProvider(session);
assertTrue(new BoxTouchFeature(session, fileid).isSupported(Home.root(), "xacjivli-éf"));
assertTrue(new BoxTouchFeature(session, fileid).isSupported(Home.root(), Optional.of("xacjivli-éf")));
}
}
@@ -22,6 +22,7 @@ import ch.cyberduck.core.exception.BackgroundException;
import ch.cyberduck.core.transfer.TransferStatus;
import java.text.MessageFormat;
import java.util.Optional;
/**
* Create new folder on server
@@ -43,10 +44,10 @@ public interface Directory<Reply> {
/**
* @param workdir Working directory in browser
* @param filename Folder name or null if unknown
* @param filename Folder name if known
* @return True if creating directory is supported in the working directory
*/
default boolean isSupported(final Path workdir, final String filename) {
default boolean isSupported(final Path workdir, final Optional<String> filename) {
try {
this.preflight(workdir, filename);
return true;
@@ -59,7 +60,7 @@ public interface Directory<Reply> {
/**
* @throws AccessDeniedException Permission failure for target directory
*/
default void preflight(final Path workdir, final String filename) throws BackgroundException {
default void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(!workdir.attributes().getPermission().isWritable()) {
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString(
"Cannot create folder {0}", "Error"), filename)).withFile(workdir);
@@ -40,7 +40,7 @@ public interface Touch<Reply> {
* @param filename Relative filename
* @return True if creating an empty file is possible.
*/
default boolean isSupported(final Path workdir, final String filename) {
default boolean isSupported(final Path workdir, final java.util.Optional<String> filename) {
try {
this.preflight(workdir, filename);
return true;
@@ -53,7 +53,7 @@ public interface Touch<Reply> {
/**
* @throws AccessDeniedException Permission failure for target directory
*/
default void preflight(final Path workdir, final String filename) throws BackgroundException {
default void preflight(final Path workdir, final java.util.Optional<String> filename) throws BackgroundException {
if(!workdir.attributes().getPermission().isWritable()) {
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString(
"Cannot create {0}", "Error"), filename)).withFile(workdir);
@@ -97,7 +97,12 @@ public class VaultRegistryCopyFeature implements Copy {
}
}
else {
proxy.preflight(source, optional);
try {
registry.find(session, source, false).getFeature(session, Copy.class, proxy).preflight(source, optional);
}
catch(VaultUnlockCancelException e) {
proxy.preflight(source, optional);
}
}
}
@@ -24,6 +24,8 @@ import ch.cyberduck.core.transfer.TransferStatus;
import ch.cyberduck.core.vault.VaultRegistry;
import ch.cyberduck.core.vault.VaultUnlockCancelException;
import java.util.Optional;
public class VaultRegistryDirectoryFeature<Reply> implements Directory<Reply> {
private final Session<?> session;
@@ -42,7 +44,7 @@ public class VaultRegistryDirectoryFeature<Reply> implements Directory<Reply> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
try {
registry.find(session, workdir, false).getFeature(session, Directory.class, proxy).preflight(workdir, filename);
}
@@ -111,7 +111,12 @@ public class VaultRegistryMoveFeature implements Move {
}
}
else {
proxy.preflight(source, optional);
try {
registry.find(session, source, false).getFeature(session, Move.class, proxy).preflight(source, optional);
}
catch(VaultUnlockCancelException e) {
proxy.preflight(source, optional);
}
}
}
@@ -24,6 +24,8 @@ import ch.cyberduck.core.transfer.TransferStatus;
import ch.cyberduck.core.vault.VaultRegistry;
import ch.cyberduck.core.vault.VaultUnlockCancelException;
import java.util.Optional;
public class VaultRegistryTouchFeature<R> implements Touch<R> {
private final Session<?> session;
@@ -42,7 +44,7 @@ public class VaultRegistryTouchFeature<R> implements Touch<R> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
try {
registry.find(session, workdir, false).getFeature(session, Touch.class, proxy).preflight(workdir, filename);
}
@@ -28,6 +28,8 @@ import ch.cyberduck.core.transfer.TransferStatus;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Optional;
public class CryptoDirectoryV6Feature<Reply> implements Directory<Reply> {
private static final Logger log = LogManager.getLogger(CryptoDirectoryV6Feature.class);
@@ -65,12 +67,12 @@ public class CryptoDirectoryV6Feature<Reply> implements Directory<Reply> {
}
@Override
public boolean isSupported(final Path workdir, final String name) {
public boolean isSupported(final Path workdir, final Optional<String> name) {
return delegate.isSupported(workdir, name);
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
delegate.preflight(cryptomator.encrypt(session, workdir), filename);
}
@@ -30,6 +30,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.EnumSet;
import java.util.Optional;
public class CryptoDirectoryV7Feature<Reply> implements Directory<Reply> {
private static final Logger log = LogManager.getLogger(CryptoDirectoryV7Feature.class);
@@ -73,12 +74,12 @@ public class CryptoDirectoryV7Feature<Reply> implements Directory<Reply> {
}
@Override
public boolean isSupported(final Path workdir, final String name) {
public boolean isSupported(final Path workdir, final Optional<String> name) {
return delegate.isSupported(workdir, name);
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
delegate.preflight(cryptomator.encrypt(session, workdir), filename);
}
@@ -31,6 +31,7 @@ import ch.cyberduck.core.transfer.TransferStatus;
import org.cryptomator.cryptolib.api.FileHeader;
import java.text.MessageFormat;
import java.util.Optional;
public class CryptoTouchFeature<Reply> implements Touch<Reply> {
@@ -65,9 +66,11 @@ public class CryptoTouchFeature<Reply> implements Touch<Reply> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
if(!cryptomator.getFilenameProvider().isValid(filename)) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename));
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(filename.isPresent()) {
if(!cryptomator.getFilenameProvider().isValid(filename.get())) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename));
}
}
proxy.preflight(cryptomator.encrypt(session, workdir), filename);
}
@@ -401,17 +401,11 @@ public class CryptomatorVaultTest {
public <T> T _getFeature(final Class<T> type) {
if(type == Directory.class) {
return (T) new Directory() {
@Override
public Path mkdir(final Write writer, final Path folder, final TransferStatus status) {
assertTrue(folder.equals(home) || folder.isChild(home));
return folder;
}
@Override
public boolean isSupported(final Path workdir, final String name) {
throw new UnsupportedOperationException();
}
};
}
return super._getFeature(type);
@@ -31,6 +31,7 @@ import org.apache.logging.log4j.Logger;
import org.cryptomator.cryptolib.api.DirectoryMetadata;
import java.util.EnumSet;
import java.util.Optional;
public class CryptoDirectoryFeature<Reply> implements Directory<Reply> {
private static final Logger log = LogManager.getLogger(CryptoDirectoryFeature.class);
@@ -87,13 +88,13 @@ public class CryptoDirectoryFeature<Reply> implements Directory<Reply> {
}
@Override
public boolean isSupported(final Path workdir, final String name) {
public boolean isSupported(final Path workdir, final Optional<String> name) {
return delegate.isSupported(workdir, name);
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
vault.getDirectoryProvider().createDirectoryId(new Path(workdir, filename, EnumSet.of(Path.Type.directory)));
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
filename.ifPresent(s -> vault.getDirectoryProvider().createDirectoryId(new Path(workdir, s, EnumSet.of(Path.Type.directory))));
delegate.preflight(vault.encrypt(session, workdir), filename);
}
@@ -31,6 +31,7 @@ import ch.cyberduck.core.transfer.TransferStatus;
import org.cryptomator.cryptolib.api.FileHeader;
import java.text.MessageFormat;
import java.util.Optional;
public class CryptoTouchFeature<Reply> implements Touch<Reply> {
@@ -65,9 +66,11 @@ public class CryptoTouchFeature<Reply> implements Touch<Reply> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
if(!vault.getFilenameProvider().isValid(filename)) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename));
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(filename.isPresent()) {
if(!vault.getFilenameProvider().isValid(filename.get())) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename));
}
}
proxy.preflight(vault.encrypt(session, workdir), filename);
}
@@ -354,11 +354,6 @@ public class CryptomatorVaultTest {
assertTrue(folder.equals(home) || folder.isChild(home));
return folder;
}
@Override
public boolean isSupported(final Path workdir, final String name) {
throw new UnsupportedOperationException();
}
};
}
return super._getFeature(type);
@@ -116,10 +116,6 @@ public class CteraAttributesFinderFeature extends DAVAttributesFinderFeature {
* @throws AccessDeniedException ACLs do not contain role
*/
protected static void assumeRole(final Path file, final Acl.Role role) throws BackgroundException {
assumeRole(file, file.getName(), role);
}
protected static void assumeRole(final Path file, final String filename, final Acl.Role role) throws BackgroundException {
final Acl acl = file.attributes().getAcl();
if(acl == Acl.EMPTY) {
log.warn("Missing ACL for {}", file);
@@ -134,11 +130,11 @@ public class CteraAttributesFinderFeature extends DAVAttributesFinderFeature {
log.warn("ACL {} for {} does not include {}", acl, file, role);
if(role == READPERMISSION) {
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString("Download {0} failed", "Error"),
filename)).withFile(file);
file.getName())).withFile(file);
}
if(role == WRITEPERMISSION) {
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString("Upload {0} failed", "Error"),
filename)).withFile(file);
file.getName())).withFile(file);
}
if(role == DELETEPERMISSION) {
throw new AccessDeniedException(MessageFormat.format(
@@ -146,7 +142,7 @@ public class CteraAttributesFinderFeature extends DAVAttributesFinderFeature {
}
if(role == CREATEDIRECTORIESPERMISSION) {
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"),
filename)).withFile(file);
file.getName())).withFile(file);
}
throw new AccessDeniedException(MessageFormat.format(
LocaleFactory.localizedString("Cannot create {0}", "Error"), file.getName())).withFile(file);
@@ -37,7 +37,7 @@ public class CteraCopyFeature extends DAVCopyFeature {
assumeRole(target, WRITEPERMISSION);
// no createfilespermission required for now
if(source.isDirectory()) {
assumeRole(target.getParent(), target.getName(), CREATEDIRECTORIESPERMISSION);
assumeRole(target, CREATEDIRECTORIESPERMISSION);
}
}
}
@@ -22,6 +22,7 @@ import ch.cyberduck.core.exception.BackgroundException;
import ch.cyberduck.core.exception.InvalidFilenameException;
import java.text.MessageFormat;
import java.util.Optional;
import static ch.cyberduck.core.ctera.CteraAttributesFinderFeature.CREATEDIRECTORIESPERMISSION;
import static ch.cyberduck.core.ctera.CteraAttributesFinderFeature.assumeRole;
@@ -34,10 +35,12 @@ public class CteraDirectoryFeature extends DAVDirectoryFeature {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
if(!validate(filename)) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename));
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(filename.isPresent()) {
if(!validate(filename.get())) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename));
}
}
assumeRole(workdir, filename, CREATEDIRECTORIESPERMISSION);
assumeRole(workdir, CREATEDIRECTORIESPERMISSION);
}
}
@@ -44,7 +44,7 @@ public class CteraMoveFeature extends DAVMoveFeature {
assumeRole(target, WRITEPERMISSION);
// no createfilespermission required for now
if(source.isDirectory()) {
assumeRole(target.getParent(), target.getName(), CREATEDIRECTORIESPERMISSION);
assumeRole(target, CREATEDIRECTORIESPERMISSION);
}
}
}
@@ -27,6 +27,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.text.MessageFormat;
import java.util.Optional;
import static ch.cyberduck.core.ctera.CteraAttributesFinderFeature.*;
@@ -39,9 +40,11 @@ public class CteraTouchFeature extends DAVTouchFeature {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
if(!validate(filename)) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename));
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(filename.isPresent()) {
if(!validate(filename.get())) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename));
}
}
// File/directory creation summary:
@@ -32,6 +32,7 @@ import org.junit.experimental.categories.Category;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Optional;
import static ch.cyberduck.core.ctera.CteraAttributesFinderFeature.CREATEDIRECTORIESPERMISSION;
import static ch.cyberduck.core.ctera.CteraAttributesFinderFeature.READPERMISSION;
@@ -54,21 +55,21 @@ public class CteraDirectoryFeatureTest extends AbstractCteraTest {
public void testPreflightFileMissingCustomProps() throws Exception {
final Path workdir = new Path(new DefaultHomeFinderService(session).find(), new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory));
workdir.setAttributes(workdir.attributes().setAcl(Acl.EMPTY));
new CteraDirectoryFeature(session).preflight(workdir, new AlphanumericRandomStringService().random());
new CteraDirectoryFeature(session).preflight(workdir, Optional.of(new AlphanumericRandomStringService().random()));
}
@Test
public void testPreflightFileAccessDeniedCustomProps() throws Exception {
final Path workdir = new Path(new DefaultHomeFinderService(session).find(), new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory));
workdir.setAttributes(workdir.attributes().setAcl(new Acl(new Acl.CanonicalUser(), READPERMISSION)));
assertThrows(AccessDeniedException.class, () -> new CteraDirectoryFeature(session).preflight(workdir, new AlphanumericRandomStringService().random()));
assertThrows(AccessDeniedException.class, () -> new CteraDirectoryFeature(session).preflight(workdir, Optional.of(new AlphanumericRandomStringService().random())));
}
@Test
public void testPreflightFileAccessGrantedCustomProps() throws Exception {
final Path workdir = new Path(new DefaultHomeFinderService(session).find(), new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory));
workdir.setAttributes(workdir.attributes().setAcl(new Acl(new Acl.CanonicalUser(), CREATEDIRECTORIESPERMISSION)));
new CteraDirectoryFeature(session).preflight(workdir, new AlphanumericRandomStringService().random());
new CteraDirectoryFeature(session).preflight(workdir, Optional.of(new AlphanumericRandomStringService().random()));
// assert no fail
}
}
@@ -26,6 +26,7 @@ import org.junit.Test;
import org.junit.experimental.categories.Category;
import java.util.EnumSet;
import java.util.Optional;
import static ch.cyberduck.core.ctera.CteraAttributesFinderFeature.CREATEDIRECTORIESPERMISSION;
import static ch.cyberduck.core.ctera.CteraAttributesFinderFeature.WRITEPERMISSION;
@@ -38,28 +39,28 @@ public class CteraTouchFeatureTest extends AbstractCteraTest {
public void testPreflightFileMissingCustomProps() throws Exception {
final Path file = new Path(new DefaultHomeFinderService(session).find(), new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory));
file.setAttributes(file.attributes().setAcl(Acl.EMPTY));
new CteraTouchFeature(session).preflight(file, new AlphanumericRandomStringService().random());
new CteraTouchFeature(session).preflight(file, Optional.of(new AlphanumericRandomStringService().random()));
}
@Test
public void testPreflightReadPermission() throws Exception {
final Path file = new Path(new DefaultHomeFinderService(session).find(), new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory));
file.setAttributes(file.attributes().setAcl(new Acl(new Acl.CanonicalUser(), CteraAttributesFinderFeature.READPERMISSION)));
assertThrows(AccessDeniedException.class, () -> new CteraTouchFeature(session).preflight(file, new AlphanumericRandomStringService().random()));
assertThrows(AccessDeniedException.class, () -> new CteraTouchFeature(session).preflight(file, Optional.of(new AlphanumericRandomStringService().random())));
}
@Test
public void testPreflightNoPermissions() throws Exception {
final Path file = new Path(new DefaultHomeFinderService(session).find(), new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory));
file.setAttributes(file.attributes().setAcl(new Acl(new Acl.CanonicalUser())));
assertThrows(AccessDeniedException.class, () -> new CteraTouchFeature(session).preflight(file, new AlphanumericRandomStringService().random()));
assertThrows(AccessDeniedException.class, () -> new CteraTouchFeature(session).preflight(file, Optional.of(new AlphanumericRandomStringService().random())));
}
@Test
public void testPreflightWritePermission() throws Exception {
final Path file = new Path(new DefaultHomeFinderService(session).find(), new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory));
file.setAttributes(file.attributes().setAcl(new Acl(new Acl.CanonicalUser(), CteraAttributesFinderFeature.WRITEPERMISSION)));
new CteraTouchFeature(session).preflight(file, new AlphanumericRandomStringService().random());
new CteraTouchFeature(session).preflight(file, Optional.of(new AlphanumericRandomStringService().random()));
// assert no fail
}
@@ -67,7 +68,7 @@ public class CteraTouchFeatureTest extends AbstractCteraTest {
public void testPreflightCreateDirectoriesPermission() throws Exception {
final Path file = new Path(new DefaultHomeFinderService(session).find(), new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory));
file.setAttributes(file.attributes().setAcl(new Acl(new Acl.CanonicalUser(), CteraAttributesFinderFeature.CREATEDIRECTORIESPERMISSION)));
new CteraTouchFeature(session).preflight(file, new AlphanumericRandomStringService().random());
new CteraTouchFeature(session).preflight(file, Optional.of(new AlphanumericRandomStringService().random()));
// assert no fail
}
@@ -79,14 +80,14 @@ public class CteraTouchFeatureTest extends AbstractCteraTest {
new Acl.UserAndRole(new Acl.CanonicalUser(), WRITEPERMISSION),
new Acl.UserAndRole(new Acl.CanonicalUser(), CREATEDIRECTORIESPERMISSION)
)));
new CteraTouchFeature(session).preflight(file, new AlphanumericRandomStringService().random());
new CteraTouchFeature(session).preflight(file, Optional.of(new AlphanumericRandomStringService().random()));
// assert no fail
}
@Test
public void testPreflightFileAccessGrantedCustomProps() throws Exception {
final Path file = new Path(new DefaultHomeFinderService(session).find(), new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory));
new CteraTouchFeature(session).preflight(file, new AlphanumericRandomStringService().random());
new CteraTouchFeature(session).preflight(file, Optional.of(new AlphanumericRandomStringService().random()));
// assert no fail
}
}
@@ -34,6 +34,7 @@ import org.apache.logging.log4j.Logger;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
public class DeepboxDirectoryFeature implements Directory<Node> {
private static final Logger log = LogManager.getLogger(DeepboxDirectoryFeature.class);
@@ -89,7 +90,7 @@ public class DeepboxDirectoryFeature implements Directory<Node> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(containerService.isInbox(workdir)) {
throw new AccessDeniedException(LocaleFactory.localizedString("Adding folders is not permitted in the inbox", "Deepbox")).withFile(workdir);
}
@@ -26,6 +26,8 @@ import ch.cyberduck.core.shared.DefaultTouchFeature;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Optional;
import static ch.cyberduck.core.deepbox.DeepboxAttributesFinderFeature.CANADDCHILDREN;
public class DeepboxTouchFeature extends DefaultTouchFeature<Node> {
@@ -39,7 +41,7 @@ public class DeepboxTouchFeature extends DefaultTouchFeature<Node> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(workdir.isRoot()) {
throw new AccessDeniedException(LocaleFactory.localizedString("Adding files is not permitted at the organisation level", "Deepbox")).withFile(workdir);
}
@@ -33,6 +33,7 @@ import org.junit.experimental.categories.Category;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Optional;
import static org.junit.Assert.*;
@@ -45,7 +46,7 @@ public class DeepboxDirectoryFeatureTest extends AbstractDeepboxTest {
final DeepboxDirectoryFeature directory = new DeepboxDirectoryFeature(session, nodeid);
final Path parent = new Path("/", EnumSet.of(Path.Type.directory));
final Path folder = new Path(parent, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory));
assertThrows(AccessDeniedException.class, () -> directory.preflight(parent, folder.getName()));
assertThrows(AccessDeniedException.class, () -> directory.preflight(parent, Optional.of(folder.getName())));
assertThrows(NotfoundException.class, () -> directory.mkdir(new DeepboxWriteFeature(session, nodeid), folder, new TransferStatus()));
}
@@ -55,7 +56,7 @@ public class DeepboxDirectoryFeatureTest extends AbstractDeepboxTest {
final DeepboxDirectoryFeature directory = new DeepboxDirectoryFeature(session, nodeid);
final Path parent = new Path("/ORG 4 - DeepBox Desktop App/", EnumSet.of(Path.Type.directory));
final Path folder = new Path(parent, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory));
assertThrows(AccessDeniedException.class, () -> directory.preflight(parent, folder.getName()));
assertThrows(AccessDeniedException.class, () -> directory.preflight(parent, Optional.of(folder.getName())));
assertThrows(NotfoundException.class, () -> directory.mkdir(new DeepboxWriteFeature(session, nodeid), folder, new TransferStatus()));
}
@@ -65,7 +66,7 @@ public class DeepboxDirectoryFeatureTest extends AbstractDeepboxTest {
final DeepboxDirectoryFeature directory = new DeepboxDirectoryFeature(session, nodeid);
final Path parent = new Path(String.format("/ORG 1 - DeepBox Desktop App/%s", DeepboxListService.SHARED), EnumSet.of(Path.Type.directory));
final Path folder = new Path(parent, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory));
assertThrows(AccessDeniedException.class, () -> directory.preflight(parent, folder.getName()));
assertThrows(AccessDeniedException.class, () -> directory.preflight(parent, Optional.of(folder.getName())));
assertThrows(NotfoundException.class, () -> directory.mkdir(new DeepboxWriteFeature(session, nodeid), folder, new TransferStatus()));
}
@@ -75,7 +76,7 @@ public class DeepboxDirectoryFeatureTest extends AbstractDeepboxTest {
final DeepboxDirectoryFeature directory = new DeepboxDirectoryFeature(session, nodeid);
final Path parent = new Path("/ORG 4 - DeepBox Desktop App/ORG 4 - DeepBox Desktop App/ORG3:Box1", EnumSet.of(Path.Type.directory));
final Path folder = new Path(parent, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory));
assertThrows(AccessDeniedException.class, () -> directory.preflight(parent, folder.getName()));
assertThrows(AccessDeniedException.class, () -> directory.preflight(parent, Optional.of(folder.getName())));
assertThrows(AccessDeniedException.class, () -> directory.mkdir(new DeepboxWriteFeature(session, nodeid), folder, new TransferStatus()));
}
@@ -85,7 +86,7 @@ public class DeepboxDirectoryFeatureTest extends AbstractDeepboxTest {
final DeepboxDirectoryFeature directory = new DeepboxDirectoryFeature(session, nodeid);
final Path parent = new Path(String.format("/ORG 1 - DeepBox Desktop App/%s/Demo 1 (1 Christian Gruber)", DeepboxListService.SHARED), EnumSet.of(Path.Type.directory));
final Path folder = new Path(parent, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory));
assertThrows(AccessDeniedException.class, () -> directory.preflight(parent, folder.getName()));
assertThrows(AccessDeniedException.class, () -> directory.preflight(parent, Optional.of(folder.getName())));
assertThrows(AccessDeniedException.class, () -> directory.mkdir(new DeepboxWriteFeature(session, nodeid), folder, new TransferStatus()));
}
@@ -95,7 +96,7 @@ public class DeepboxDirectoryFeatureTest extends AbstractDeepboxTest {
final DeepboxDirectoryFeature directory = new DeepboxDirectoryFeature(session, nodeid);
final Path parent = new Path("/ORG 4 - DeepBox Desktop App/ORG 4 - DeepBox Desktop App/ORG3:Box1/Inbox", EnumSet.of(Path.Type.directory));
final Path folder = new Path(parent, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory));
assertThrows(AccessDeniedException.class, () -> directory.preflight(parent, folder.getName()));
assertThrows(AccessDeniedException.class, () -> directory.preflight(parent, Optional.of(folder.getName())));
assertThrows(InteroperabilityException.class, () -> directory.mkdir(new DeepboxWriteFeature(session, nodeid), folder, new TransferStatus()));
}
@@ -105,7 +106,7 @@ public class DeepboxDirectoryFeatureTest extends AbstractDeepboxTest {
final DeepboxDirectoryFeature directory = new DeepboxDirectoryFeature(session, nodeid);
final Path parent = new Path(String.format("/ORG 1 - DeepBox Desktop App/%s/Demo 1 (1 Christian Gruber)/Inbox", DeepboxListService.SHARED), EnumSet.of(Path.Type.directory));
final Path folder = new Path(parent, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory));
assertThrows(AccessDeniedException.class, () -> directory.preflight(parent, folder.getName()));
assertThrows(AccessDeniedException.class, () -> directory.preflight(parent, Optional.of(folder.getName())));
assertThrows(InteroperabilityException.class, () -> directory.mkdir(new DeepboxWriteFeature(session, nodeid), folder, new TransferStatus()));
}
@@ -115,7 +116,7 @@ public class DeepboxDirectoryFeatureTest extends AbstractDeepboxTest {
final DeepboxDirectoryFeature directory = new DeepboxDirectoryFeature(session, nodeid);
final Path parent = new Path("/ORG 4 - DeepBox Desktop App/ORG 4 - DeepBox Desktop App/ORG3:Box1/Trash", EnumSet.of(Path.Type.directory));
final Path folder = new Path(parent, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory));
assertThrows(AccessDeniedException.class, () -> directory.preflight(parent, folder.getName()));
assertThrows(AccessDeniedException.class, () -> directory.preflight(parent, Optional.of(folder.getName())));
assertThrows(AccessDeniedException.class, () -> directory.mkdir(new DeepboxWriteFeature(session, nodeid), folder, new TransferStatus()));
}
@@ -150,7 +151,7 @@ public class DeepboxDirectoryFeatureTest extends AbstractDeepboxTest {
final DeepboxIdProvider nodeid = new DeepboxIdProvider(session);
final Path documents = new Path("/ORG 4 - DeepBox Desktop App/ORG 4 - DeepBox Desktop App/ORG3:Box1/Documents/", EnumSet.of(Path.Type.directory, Path.Type.volume));
final Path test = new DeepboxDirectoryFeature(session, nodeid).mkdir(new DeepboxWriteFeature(session, nodeid), new Path(documents, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)), new TransferStatus());
new DeepboxDirectoryFeature(session, nodeid).preflight(documents.withAttributes(new DeepboxAttributesFinderFeature(session, nodeid).find(documents)), test.getName());
new DeepboxDirectoryFeature(session, nodeid).preflight(documents.withAttributes(new DeepboxAttributesFinderFeature(session, nodeid).find(documents)), Optional.of(test.getName()));
assertTrue(new DeepboxFindFeature(session, nodeid).find(test));
new DeepboxDeleteFeature(session, nodeid).delete(Collections.singletonList(test), LoginCallback.noop, new Delete.DisabledCallback());
}
@@ -34,6 +34,7 @@ import org.junit.experimental.categories.Category;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Optional;
import static ch.cyberduck.core.deepbox.DeepboxAttributesFinderFeature.CANADDCHILDREN;
import static org.junit.Assert.*;
@@ -44,7 +45,7 @@ public class DeepboxTouchFeatureTest extends AbstractDeepboxTest {
@Test
public void testTouchRoot() throws Exception {
final DeepboxIdProvider fileid = new DeepboxIdProvider(session);
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, fileid).preflight(Home.root(), new AlphanumericRandomStringService().random()));
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, fileid).preflight(Home.root(), Optional.of(new AlphanumericRandomStringService().random())));
assertThrows(NotfoundException.class, () -> new DeepboxTouchFeature(session, fileid).touch(new DeepboxWriteFeature(session, fileid), new Path(new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)), new TransferStatus()));
}
@@ -53,7 +54,7 @@ public class DeepboxTouchFeatureTest extends AbstractDeepboxTest {
final DeepboxIdProvider fileid = new DeepboxIdProvider(session);
final Path documents = new Path("/ORG 4 - DeepBox Desktop App/ORG 4 - DeepBox Desktop App/ORG3:Box1/Documents/", EnumSet.of(Path.Type.directory, Path.Type.volume));
final Path test = new DeepboxTouchFeature(session, fileid).touch(new DeepboxWriteFeature(session, fileid), new Path(documents, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)), new TransferStatus());
new DeepboxTouchFeature(session, fileid).preflight(documents.withAttributes(new DeepboxAttributesFinderFeature(session, fileid).find(documents)), test.getName());
new DeepboxTouchFeature(session, fileid).preflight(documents.withAttributes(new DeepboxAttributesFinderFeature(session, fileid).find(documents)), Optional.of(test.getName()));
assertTrue(new DeepboxFindFeature(session, fileid).find(test));
new DeepboxDeleteFeature(session, fileid).delete(Collections.singletonList(test), LoginCallback.noop, new Delete.DisabledCallback());
}
@@ -73,7 +74,7 @@ public class DeepboxTouchFeatureTest extends AbstractDeepboxTest {
final Path folder = new Path("/ORG 4 - DeepBox Desktop App/", EnumSet.of(Path.Type.directory, Path.Type.volume));
final PathAttributes attributes = new DeepboxAttributesFinderFeature(session, nodeid).find(folder);
assertEquals(Acl.EMPTY, attributes.getAcl());
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, nodeid).preflight(folder.withAttributes(attributes), new AlphanumericRandomStringService().random()));
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, nodeid).preflight(folder.withAttributes(attributes), Optional.of(new AlphanumericRandomStringService().random())));
}
@Test
@@ -82,7 +83,7 @@ public class DeepboxTouchFeatureTest extends AbstractDeepboxTest {
final Path folder = new Path("/ORG 4 - DeepBox Desktop App/ORG 4 - DeepBox Desktop App/", EnumSet.of(Path.Type.directory, Path.Type.volume));
final PathAttributes attributes = new DeepboxAttributesFinderFeature(session, nodeid).find(folder);
assertEquals(Acl.EMPTY, attributes.getAcl());
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, nodeid).preflight(folder.withAttributes(attributes), new AlphanumericRandomStringService().random()));
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, nodeid).preflight(folder.withAttributes(attributes), Optional.of(new AlphanumericRandomStringService().random())));
}
@Test
@@ -91,7 +92,7 @@ public class DeepboxTouchFeatureTest extends AbstractDeepboxTest {
final Path folder = new Path("/ORG 4 - DeepBox Desktop App/ORG 4 - DeepBox Desktop App/ORG3:Box1", EnumSet.of(Path.Type.directory, Path.Type.volume));
final PathAttributes attributes = new DeepboxAttributesFinderFeature(session, nodeid).find(folder);
assertEquals(Acl.EMPTY, attributes.getAcl());
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, nodeid).preflight(folder.withAttributes(attributes), new AlphanumericRandomStringService().random()));
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, nodeid).preflight(folder.withAttributes(attributes), Optional.of(new AlphanumericRandomStringService().random())));
}
@Test
@@ -102,9 +103,9 @@ public class DeepboxTouchFeatureTest extends AbstractDeepboxTest {
assertTrue(new BoxRestControllerApi(session.getClient()).getBox(ORG4_DEEPBOX4, ORG4_DEEPBOX4_BOX1).getBoxPolicy().isCanAddQueue());
assertTrue(attributes.getAcl().get(new Acl.CanonicalUser()).contains(CANADDCHILDREN));
// assert no fail
new DeepboxTouchFeature(session, nodeid).preflight(folder.withAttributes(attributes), new AlphanumericRandomStringService().random());
new DeepboxTouchFeature(session, nodeid).preflight(folder.withAttributes(attributes), Optional.of(new AlphanumericRandomStringService().random()));
// DeepBox inbox is flat
assertThrows(AccessDeniedException.class, () -> new DeepboxDirectoryFeature(session, nodeid).preflight(folder.withAttributes(attributes), new AlphanumericRandomStringService().random()));
assertThrows(AccessDeniedException.class, () -> new DeepboxDirectoryFeature(session, nodeid).preflight(folder.withAttributes(attributes), Optional.of(new AlphanumericRandomStringService().random())));
}
@Test
@@ -114,8 +115,8 @@ public class DeepboxTouchFeatureTest extends AbstractDeepboxTest {
final PathAttributes attributes = new DeepboxAttributesFinderFeature(session, nodeid).find(folder);
assertFalse(new BoxRestControllerApi(session.getClient()).getBox(ORG1_DEEPBOX1, ORG1_DEEPBOX1_BOX1).getBoxPolicy().isCanAddQueue());
assertFalse(attributes.getAcl().get(new Acl.CanonicalUser()).contains(CANADDCHILDREN));
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, nodeid).preflight(folder.withAttributes(attributes), new AlphanumericRandomStringService().random()));
assertThrows(AccessDeniedException.class, () -> new DeepboxDirectoryFeature(session, nodeid).preflight(folder.withAttributes(attributes), new AlphanumericRandomStringService().random()));
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, nodeid).preflight(folder.withAttributes(attributes), Optional.of(new AlphanumericRandomStringService().random())));
assertThrows(AccessDeniedException.class, () -> new DeepboxDirectoryFeature(session, nodeid).preflight(folder.withAttributes(attributes), Optional.of(new AlphanumericRandomStringService().random())));
}
@Test
@@ -126,9 +127,9 @@ public class DeepboxTouchFeatureTest extends AbstractDeepboxTest {
assertTrue(new BoxRestControllerApi(session.getClient()).getBox(ORG4_DEEPBOX4, ORG4_DEEPBOX4_BOX1).getBoxPolicy().isCanAddFilesRoot());
assertTrue(attributes.getAcl().get(new Acl.CanonicalUser()).contains(CANADDCHILDREN));
// assert no fail
new DeepboxTouchFeature(session, nodeid).preflight(folder.withAttributes(attributes), new AlphanumericRandomStringService().random());
new DeepboxTouchFeature(session, nodeid).preflight(folder.withAttributes(attributes), Optional.of(new AlphanumericRandomStringService().random()));
// assert no fail
new DeepboxDirectoryFeature(session, nodeid).preflight(folder.withAttributes(attributes), new AlphanumericRandomStringService().random());
new DeepboxDirectoryFeature(session, nodeid).preflight(folder.withAttributes(attributes), Optional.of(new AlphanumericRandomStringService().random()));
}
@Test
@@ -138,8 +139,8 @@ public class DeepboxTouchFeatureTest extends AbstractDeepboxTest {
final PathAttributes attributes = new DeepboxAttributesFinderFeature(session, nodeid).find(folder);
assertFalse(new BoxRestControllerApi(session.getClient()).getBox(ORG1_DEEPBOX1, ORG1_DEEPBOX1_BOX1).getBoxPolicy().isCanAddFilesRoot());
assertFalse(attributes.getAcl().get(new Acl.CanonicalUser()).contains(CANADDCHILDREN));
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, nodeid).preflight(folder.withAttributes(attributes), new AlphanumericRandomStringService().random()));
assertThrows(AccessDeniedException.class, () -> new DeepboxDirectoryFeature(session, nodeid).preflight(folder.withAttributes(attributes), new AlphanumericRandomStringService().random()));
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, nodeid).preflight(folder.withAttributes(attributes), Optional.of(new AlphanumericRandomStringService().random())));
assertThrows(AccessDeniedException.class, () -> new DeepboxDirectoryFeature(session, nodeid).preflight(folder.withAttributes(attributes), Optional.of(new AlphanumericRandomStringService().random())));
}
@Test
@@ -148,8 +149,8 @@ public class DeepboxTouchFeatureTest extends AbstractDeepboxTest {
final Path folder = new Path("/ORG 1 - DeepBox Desktop App/ORG 1 - DeepBox Desktop App/ORG1:Box1/Trash/", EnumSet.of(Path.Type.directory, Path.Type.volume));
final PathAttributes attributes = new DeepboxAttributesFinderFeature(session, nodeid).find(folder);
assertFalse(attributes.getAcl().get(new Acl.CanonicalUser()).contains(CANADDCHILDREN));
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, nodeid).preflight(folder.withAttributes(attributes), new AlphanumericRandomStringService().random()));
assertThrows(AccessDeniedException.class, () -> new DeepboxDirectoryFeature(session, nodeid).preflight(folder.withAttributes(attributes), new AlphanumericRandomStringService().random()));
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, nodeid).preflight(folder.withAttributes(attributes), Optional.of(new AlphanumericRandomStringService().random())));
assertThrows(AccessDeniedException.class, () -> new DeepboxDirectoryFeature(session, nodeid).preflight(folder.withAttributes(attributes), Optional.of(new AlphanumericRandomStringService().random())));
}
@Test
@@ -160,9 +161,9 @@ public class DeepboxTouchFeatureTest extends AbstractDeepboxTest {
assertTrue(new CoreRestControllerApi(session.getClient()).getNodeInfo(attributes.getFileId(), null, null, null).getNode().getPolicy().isCanAddChildren());
assertTrue(attributes.getAcl().get(new Acl.CanonicalUser()).contains(CANADDCHILDREN));
// assert no fail
new DeepboxTouchFeature(session, nodeid).preflight(folder.withAttributes(attributes), new AlphanumericRandomStringService().random());
new DeepboxTouchFeature(session, nodeid).preflight(folder.withAttributes(attributes), Optional.of(new AlphanumericRandomStringService().random()));
// assert no fail
new DeepboxDirectoryFeature(session, nodeid).preflight(folder.withAttributes(attributes), new AlphanumericRandomStringService().random());
new DeepboxDirectoryFeature(session, nodeid).preflight(folder.withAttributes(attributes), Optional.of(new AlphanumericRandomStringService().random()));
}
@Test
@@ -172,8 +173,8 @@ public class DeepboxTouchFeatureTest extends AbstractDeepboxTest {
final PathAttributes attributes = new DeepboxAttributesFinderFeature(session, nodeid).find(folder);
assertFalse(new CoreRestControllerApi(session.getClient()).getNodeInfo(attributes.getFileId(), null, null, null).getNode().getPolicy().isCanAddChildren());
assertFalse(attributes.getAcl().get(new Acl.CanonicalUser()).contains(CANADDCHILDREN));
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, nodeid).preflight(folder.withAttributes(attributes), new AlphanumericRandomStringService().random()));
assertThrows(AccessDeniedException.class, () -> new DeepboxDirectoryFeature(session, nodeid).preflight(folder.withAttributes(attributes), new AlphanumericRandomStringService().random()));
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, nodeid).preflight(folder.withAttributes(attributes), Optional.of(new AlphanumericRandomStringService().random())));
assertThrows(AccessDeniedException.class, () -> new DeepboxDirectoryFeature(session, nodeid).preflight(folder.withAttributes(attributes), Optional.of(new AlphanumericRandomStringService().random())));
}
@Test
@@ -183,8 +184,8 @@ public class DeepboxTouchFeatureTest extends AbstractDeepboxTest {
final PathAttributes attributes = new DeepboxAttributesFinderFeature(session, nodeid).find(folder);
assertFalse(new CoreRestControllerApi(session.getClient()).getNodeInfo(attributes.getFileId(), null, null, null).getNode().getPolicy().isCanAddChildren());
assertFalse(attributes.getAcl().get(new Acl.CanonicalUser()).contains(CANADDCHILDREN));
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, nodeid).preflight(folder.withAttributes(attributes), new AlphanumericRandomStringService().random()));
assertThrows(AccessDeniedException.class, () -> new DeepboxDirectoryFeature(session, nodeid).preflight(folder.withAttributes(attributes), new AlphanumericRandomStringService().random()));
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, nodeid).preflight(folder.withAttributes(attributes), Optional.of(new AlphanumericRandomStringService().random())));
assertThrows(AccessDeniedException.class, () -> new DeepboxDirectoryFeature(session, nodeid).preflight(folder.withAttributes(attributes), Optional.of(new AlphanumericRandomStringService().random())));
}
@Test
@@ -192,7 +193,7 @@ public class DeepboxTouchFeatureTest extends AbstractDeepboxTest {
final DeepboxIdProvider nodeid = new DeepboxIdProvider(session);
final Path parent = new Path("/ORG 4 - DeepBox Desktop App/ORG 4 - DeepBox Desktop App/ORG3:Box1/Trash", EnumSet.of(Path.Type.directory));
final Path folder = new Path(parent, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory));
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, nodeid).preflight(parent, folder.getName()));
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, nodeid).preflight(parent, Optional.of(folder.getName())));
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, nodeid).touch(new DeepboxWriteFeature(session, nodeid), folder, new TransferStatus()));
}
@@ -201,7 +202,7 @@ public class DeepboxTouchFeatureTest extends AbstractDeepboxTest {
final DeepboxIdProvider nodeid = new DeepboxIdProvider(session);
final Path parent = new Path(String.format("/ORG 1 - DeepBox Desktop App/%s", DeepboxListService.SHARED), EnumSet.of(Path.Type.directory));
final Path file = new Path(parent, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory));
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, nodeid).preflight(parent, file.getName()));
assertThrows(AccessDeniedException.class, () -> new DeepboxTouchFeature(session, nodeid).preflight(parent, Optional.of(file.getName())));
assertThrows(NotfoundException.class, () -> new DeepboxTouchFeature(session, nodeid).touch(new DeepboxWriteFeature(session, nodeid), file, new TransferStatus()));
}
}
@@ -31,6 +31,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.EnumSet;
import java.util.Optional;
public class SDSDelegatingWriteFeature implements MultipartWrite<Node> {
private static final Logger log = LogManager.getLogger(SDSDelegatingWriteFeature.class);
@@ -68,7 +69,7 @@ public class SDSDelegatingWriteFeature implements MultipartWrite<Node> {
@Override
public void preflight(final Path file) throws BackgroundException {
new SDSTouchFeature(session, nodeid).preflight(file.getParent(), file.getName());
new SDSTouchFeature(session, nodeid).preflight(file.getParent(), Optional.of(file.getName()));
}
@Override
@@ -32,12 +32,12 @@ import ch.cyberduck.core.sds.io.swagger.client.model.EncryptRoomRequest;
import ch.cyberduck.core.sds.io.swagger.client.model.Node;
import ch.cyberduck.core.transfer.TransferStatus;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.text.MessageFormat;
import java.util.EnumSet;
import java.util.Optional;
public class SDSDirectoryFeature implements Directory<Node> {
private static final Logger log = LogManager.getLogger(SDSDirectoryFeature.class);
@@ -102,15 +102,17 @@ public class SDSDirectoryFeature implements Directory<Node> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(workdir.isRoot()) {
if(!HostPreferencesFactory.get(session.getHost()).getBoolean("sds.create.dataroom.enable")) {
log.warn("Disallow creating new top level data room {}", filename);
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename)).withFile(workdir);
}
}
if(!SDSTouchFeature.validate(filename)) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename));
if(filename.isPresent()) {
if(!SDSTouchFeature.validate(filename.get())) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename));
}
}
final SDSPermissionsFeature permissions = new SDSPermissionsFeature(session, nodeid);
if(!permissions.containsRole(workdir, SDSPermissionsFeature.CREATE_ROLE)) {
@@ -33,6 +33,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.text.MessageFormat;
import java.util.Optional;
public class SDSTouchFeature extends DefaultTouchFeature<Node> {
private static final Logger log = LogManager.getLogger(SDSTouchFeature.class);
@@ -59,12 +60,14 @@ public class SDSTouchFeature extends DefaultTouchFeature<Node> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(workdir.isRoot()) {
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename)).withFile(workdir);
}
if(!validate(filename)) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename));
if(filename.isPresent()) {
if(!validate(filename.get())) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename));
}
}
final SDSPermissionsFeature permissions = new SDSPermissionsFeature(session, nodeid);
if(!permissions.containsRole(workdir, SDSPermissionsFeature.CREATE_ROLE)
@@ -35,7 +35,6 @@ import ch.cyberduck.core.transfer.TransferStatus;
import ch.cyberduck.test.IntegrationTest;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.junit.experimental.categories.Category;
@@ -44,6 +43,7 @@ import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Optional;
import static org.junit.Assert.*;
@@ -53,9 +53,9 @@ public class SDSTouchFeatureTest extends AbstractSDSTest {
@Test
public void testSupported() {
final SDSNodeIdProvider nodeid = new SDSNodeIdProvider(session);
assertTrue(new SDSTouchFeature(session, nodeid).isSupported(new Path(new Path(new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)), new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)), StringUtils.EMPTY));
assertTrue(new SDSTouchFeature(session, nodeid).isSupported(new Path(new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)), StringUtils.EMPTY));
assertFalse(new SDSTouchFeature(session, nodeid).isSupported(new Path("/", EnumSet.of(Path.Type.directory)), StringUtils.EMPTY));
assertTrue(new SDSTouchFeature(session, nodeid).isSupported(new Path(new Path(new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)), new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)), Optional.empty()));
assertTrue(new SDSTouchFeature(session, nodeid).isSupported(new Path(new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)), Optional.empty()));
assertFalse(new SDSTouchFeature(session, nodeid).isSupported(new Path("/", EnumSet.of(Path.Type.directory)), Optional.empty()));
}
@Test(expected = BackgroundException.class)
@@ -77,8 +77,8 @@ public class SDSTouchFeatureTest extends AbstractSDSTest {
new SDSDirectS3MultipartWriteFeature(session, nodeid), new Path(new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory, Path.Type.volume)), new TransferStatus());
try {
final SDSTouchFeature feature = new SDSTouchFeature(session, nodeid);
assertFalse(feature.isSupported(room, "?"));
assertThrows(InvalidFilenameException.class, () -> feature.preflight(room, "?"));
assertFalse(feature.isSupported(room, Optional.of("?")));
assertThrows(InvalidFilenameException.class, () -> feature.preflight(room, Optional.of("?")));
feature.touch(new SDSDirectS3MultipartWriteFeature(session, nodeid), new Path(room, "CON", EnumSet.of(Path.Type.file)), new TransferStatus());
}
catch(InteroperabilityException e) {
@@ -97,8 +97,8 @@ public class SDSTouchFeatureTest extends AbstractSDSTest {
new SDSDirectS3MultipartWriteFeature(session, nodeid), new Path(new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory, Path.Type.volume)), new TransferStatus());
try {
final SDSTouchFeature feature = new SDSTouchFeature(session, nodeid);
assertFalse(feature.isSupported(room, "?"));
assertThrows(InvalidFilenameException.class, () -> feature.preflight(room, "?"));
assertFalse(feature.isSupported(room, Optional.of("?")));
assertThrows(InvalidFilenameException.class, () -> feature.preflight(room, Optional.of("?")));
feature.touch(new SDSDirectS3MultipartWriteFeature(session, nodeid), new Path(room, "?", EnumSet.of(Path.Type.file)), new TransferStatus());
}
catch(InteroperabilityException e) {
@@ -132,7 +132,7 @@ public class SDSTouchFeatureTest extends AbstractSDSTest {
final long quota = 1L + PreferencesFactory.get().getInteger("sds.upload.multipart.chunksize");
updateRoomRequest.setQuota(quota);
assertEquals(quota, new NodesApi(session.getClient()).updateRoom(updateRoomRequest, Long.valueOf(room.attributes().getVersionId()), null).getQuota(), 0L);
assertTrue(new SDSTouchFeature(session, nodeid).isSupported(room.withAttributes(new SDSAttributesFinderFeature(session, nodeid).find(room)), StringUtils.EMPTY));
assertTrue(new SDSTouchFeature(session, nodeid).isSupported(room.withAttributes(new SDSAttributesFinderFeature(session, nodeid).find(room)), Optional.empty()));
assertEquals(quota, room.attributes().getQuota().available, 0L);
final byte[] content = RandomUtils.nextBytes(2);
final TransferStatus status = new TransferStatus();
@@ -150,7 +150,7 @@ public class SDSTouchFeatureTest extends AbstractSDSTest {
}
}
while(attr.getSize() != 2L);
assertFalse(new SDSTouchFeature(session, nodeid).isSupported(room.withAttributes(attr), StringUtils.EMPTY));
assertFalse(new SDSTouchFeature(session, nodeid).isSupported(room.withAttributes(attr), Optional.empty()));
assertEquals(quota, attr.getQuota().available, 0L);
assertEquals(2L, attr.getSize());
new SDSDeleteFeature(session, nodeid).delete(Arrays.asList(test, room), LoginCallback.noop, new Delete.DisabledCallback());
@@ -25,6 +25,7 @@ import ch.cyberduck.core.features.Write;
import ch.cyberduck.core.transfer.TransferStatus;
import java.text.MessageFormat;
import java.util.Optional;
import com.dropbox.core.DbxException;
import com.dropbox.core.v2.files.CreateFolderResult;
@@ -54,9 +55,11 @@ public class DropboxDirectoryFeature implements Directory<Metadata> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
if(!DropboxTouchFeature.validate(filename)) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename));
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(filename.isPresent()) {
if(!DropboxTouchFeature.validate(filename.get())) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename));
}
}
}
}
@@ -24,6 +24,7 @@ import ch.cyberduck.core.shared.DefaultTouchFeature;
import org.apache.commons.lang3.StringUtils;
import java.text.MessageFormat;
import java.util.Optional;
import com.dropbox.core.v2.files.Metadata;
@@ -42,9 +43,11 @@ public class DropboxTouchFeature extends DefaultTouchFeature<Metadata> {
* @throws InvalidFilenameException If restricted filename
*/
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
if(!validate(filename)) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename));
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(filename.isPresent()) {
if(!validate(filename.get())) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename));
}
}
}
@@ -41,6 +41,7 @@ import org.junit.experimental.categories.Category;
import java.io.ByteArrayInputStream;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Optional;
import static org.junit.Assert.*;
@@ -51,7 +52,7 @@ public class DropboxTouchFeatureTest extends AbstractDropboxTest {
public void testDisallowedName() throws Exception {
final DropboxTouchFeature touch = new DropboxTouchFeature(session);
final Path file = new Path(new DefaultHomeFinderService(session).find(), String.format("~%s.tmp", new AlphanumericRandomStringService().random()), EnumSet.of(Path.Type.file));
assertFalse(touch.isSupported(new DefaultHomeFinderService(session).find(), file.getName()));
assertFalse(touch.isSupported(new DefaultHomeFinderService(session).find(), Optional.of(file.getName())));
touch.touch(new DropboxWriteFeature(session), file, new TransferStatus());
}
@@ -38,6 +38,7 @@ import org.apache.logging.log4j.Logger;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.Optional;
public class EueDirectoryFeature implements Directory<EueWriteFeature.Chunk> {
private static final Logger log = LogManager.getLogger(EueDirectoryFeature.class);
@@ -89,9 +90,11 @@ public class EueDirectoryFeature implements Directory<EueWriteFeature.Chunk> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
if(!EueTouchFeature.validate(filename)) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename));
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(filename.isPresent()) {
if(!EueTouchFeature.validate(filename.get())) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename));
}
}
}
}
@@ -24,6 +24,7 @@ import ch.cyberduck.core.shared.DefaultTouchFeature;
import org.apache.commons.lang3.StringUtils;
import java.text.MessageFormat;
import java.util.Optional;
public class EueTouchFeature extends DefaultTouchFeature<EueWriteFeature.Chunk> {
@@ -32,9 +33,11 @@ public class EueTouchFeature extends DefaultTouchFeature<EueWriteFeature.Chunk>
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
if(!validate(filename)) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename));
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(filename.isPresent()) {
if(!validate(filename.get())) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename));
}
}
}
@@ -30,6 +30,7 @@ import org.junit.experimental.categories.Category;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Optional;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;
@@ -40,12 +41,12 @@ public class EueTouchFeatureTest extends AbstractEueSessionTest {
@Test
public void testSupported() {
final EueResourceIdProvider fileid = new EueResourceIdProvider(session);
assertFalse(new EueTouchFeature(session, fileid).isSupported(new Path("/", EnumSet.of(Path.Type.directory)), "f >f"));
assertFalse(new EueTouchFeature(session, fileid).isSupported(new Path("/", EnumSet.of(Path.Type.directory)), "f "));
assertFalse(new EueTouchFeature(session, fileid).isSupported(new Path("/", EnumSet.of(Path.Type.directory)), "f."));
assertFalse(new EueTouchFeature(session, fileid).isSupported(new Path("/", EnumSet.of(Path.Type.directory)), Optional.of("f >f")));
assertFalse(new EueTouchFeature(session, fileid).isSupported(new Path("/", EnumSet.of(Path.Type.directory)), Optional.of("f ")));
assertFalse(new EueTouchFeature(session, fileid).isSupported(new Path("/", EnumSet.of(Path.Type.directory)), Optional.of("f.")));
// max path length exceeded. Allowed are 250, but the length was 255
assertFalse(new EueTouchFeature(session, fileid).isSupported(new Path("/", EnumSet.of(Path.Type.directory)),
new AsciiRandomStringService(255).random()));
Optional.of(new AsciiRandomStringService(255).random())));
}
@Test
@@ -27,6 +27,7 @@ import ch.cyberduck.core.transfer.TransferStatus;
import org.apache.commons.net.ftp.FTPReply;
import java.io.IOException;
import java.util.Optional;
public class FTPDirectoryFeature implements Directory<Void> {
@@ -57,7 +58,7 @@ public class FTPDirectoryFeature implements Directory<Void> {
}
@Override
public void preflight(final Path workdir, final String filename) {
public void preflight(final Path workdir, final Optional<String> filename) {
// Skip checking permission mask
}
}
@@ -18,6 +18,8 @@ package ch.cyberduck.core.ftp;
import ch.cyberduck.core.Path;
import ch.cyberduck.core.shared.DefaultTouchFeature;
import java.util.Optional;
public class FTPTouchFeature extends DefaultTouchFeature<Void> {
public FTPTouchFeature(final FTPSession session) {
@@ -25,7 +27,7 @@ public class FTPTouchFeature extends DefaultTouchFeature<Void> {
}
@Override
public void preflight(final Path workdir, final String filename) {
public void preflight(final Path workdir, final Optional<String> filename) {
// Skip checking permission mask
}
}
@@ -17,7 +17,6 @@ package ch.cyberduck.core.googledrive;
import ch.cyberduck.core.DefaultPathAttributes;
import ch.cyberduck.core.Path;
import ch.cyberduck.core.PathAttributes;
import ch.cyberduck.core.SimplePathPredicate;
import ch.cyberduck.core.UUIDRandomStringService;
import ch.cyberduck.core.exception.BackgroundException;
@@ -30,6 +29,7 @@ import ch.cyberduck.core.transfer.TransferStatus;
import java.io.IOException;
import java.util.Collections;
import java.util.Optional;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.model.File;
@@ -81,7 +81,7 @@ public class DriveDirectoryFeature implements Directory<File> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
new DriveTouchFeature(session, fileid).preflight(workdir, filename);
}
}
@@ -30,6 +30,7 @@ import ch.cyberduck.core.transfer.TransferStatus;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.Optional;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.model.File;
@@ -71,7 +72,7 @@ public class DriveTouchFeature implements Touch<File> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(workdir.isRoot()) {
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename)).withFile(workdir);
}
@@ -32,6 +32,7 @@ import org.jets3t.service.utils.ServiceUtils;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.EnumSet;
import java.util.Optional;
import com.google.api.services.storage.Storage;
import com.google.api.services.storage.model.Bucket;
@@ -77,20 +78,19 @@ public class GoogleStorageDirectoryFeature implements Directory<StorageObject> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(workdir.isRoot()) {
if(StringUtils.isNotBlank(filename)) {
if(StringUtils.startsWith(filename, "goog")) {
if(filename.isPresent()) {
if(StringUtils.startsWith(filename.get(), "goog")) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename));
}
if(StringUtils.contains(filename, "google")) {
if(StringUtils.contains(filename.get(), "google")) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename));
}
if(!ServiceUtils.isBucketNameValidDNSName(filename)) {
if(!ServiceUtils.isBucketNameValidDNSName(filename.get())) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename));
}
}
}
}
}
@@ -22,6 +22,7 @@ import ch.cyberduck.core.exception.BackgroundException;
import ch.cyberduck.core.shared.DefaultTouchFeature;
import java.text.MessageFormat;
import java.util.Optional;
import com.google.api.services.storage.model.StorageObject;
@@ -32,7 +33,7 @@ public class GoogleStorageTouchFeature extends DefaultTouchFeature<StorageObject
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
// Creating files is only possible inside a bucket.
if(workdir.isRoot()) {
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename)).withFile(workdir);
@@ -22,8 +22,6 @@ import ch.cyberduck.core.features.Touch;
import ch.cyberduck.core.features.Write;
import ch.cyberduck.core.transfer.TransferStatus;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.irods.irods4j.high_level.connection.IRODSConnection;
import org.irods.irods4j.low_level.api.IRODSApi;
import org.irods.irods4j.low_level.api.IRODSException;
@@ -32,6 +30,8 @@ import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;
public class IRODSTouchFeature implements Touch {
private static final ObjectMapper mapper = new ObjectMapper();
@@ -66,9 +66,4 @@ public class IRODSTouchFeature implements Touch {
throw new DefaultIOExceptionMappingService().map("Cannot create {0}", e, file);
}
}
@Override
public boolean isSupported(final Path workdir, final String filename) {
return true;
}
}
@@ -26,11 +26,12 @@ import ch.cyberduck.core.transfer.TransferStatus;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Optional;
import com.joyent.manta.exception.MantaClientHttpResponseException;
import com.joyent.manta.exception.MantaException;
public class MantaDirectoryFeature implements Directory {
public class MantaDirectoryFeature implements Directory<Void> {
private final MantaSession session;
@@ -39,7 +40,7 @@ public class MantaDirectoryFeature implements Directory {
}
@Override
public Path mkdir(final Write writer, final Path folder, final TransferStatus status) throws BackgroundException {
public Path mkdir(final Write<Void> writer, final Path folder, final TransferStatus status) throws BackgroundException {
try {
session.getClient().putDirectory(folder.getAbsolute());
return folder;
@@ -56,7 +57,7 @@ public class MantaDirectoryFeature implements Directory {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(!session.isUserWritable(workdir)) {
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename)).withFile(workdir);
}
@@ -26,6 +26,7 @@ import ch.cyberduck.core.transfer.TransferStatus;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Optional;
import com.joyent.manta.client.MantaObjectResponse;
import com.joyent.manta.exception.MantaClientHttpResponseException;
@@ -60,7 +61,7 @@ public class MantaTouchFeature implements Touch<Void> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(!session.isUserWritable(workdir)) {
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename)).withFile(workdir);
}
@@ -34,6 +34,7 @@ import org.nuxeo.onedrive.client.types.DriveItem;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Optional;
public class GraphDirectoryFeature implements Directory<DriveItem.Metadata> {
@@ -68,7 +69,7 @@ public class GraphDirectoryFeature implements Directory<DriveItem.Metadata> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(!session.isAccessible(workdir)) {
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename)).withFile(workdir);
}
@@ -37,6 +37,7 @@ import org.nuxeo.onedrive.client.types.DriveItem;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Optional;
public class GraphTouchFeature implements Touch<DriveItem.Metadata> {
@@ -70,7 +71,7 @@ public class GraphTouchFeature implements Touch<DriveItem.Metadata> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(!session.isAccessible(workdir)) {
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename)).withFile(workdir);
}
@@ -32,6 +32,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
import java.util.Optional;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
@@ -107,11 +108,11 @@ public class OfflineGraphDirectoryTouchFeatureTest {
if(feature instanceof Touch) {
final Touch touch = (Touch) feature;
assertEquals(String.format("Create \"%s\" in \"%s\".", name, parent.getAbsolute()), testCase.isValid, touch.isSupported(parent, name));
assertEquals(String.format("Create \"%s\" in \"%s\".", name, parent.getAbsolute()), testCase.isValid, touch.isSupported(parent, Optional.of(name)));
}
else if(feature instanceof Directory) {
final Directory directory = (Directory) feature;
assertEquals(String.format("Create \"%s\" in \"%s\".", name, parent.getAbsolute()), testCase.isValid, directory.isSupported(parent, name));
assertEquals(String.format("Create \"%s\" in \"%s\".", name, parent.getAbsolute()), testCase.isValid, directory.isSupported(parent, Optional.of(name)));
}
else {
fail();
@@ -25,6 +25,7 @@ import ch.cyberduck.core.exception.BackgroundException;
import ch.cyberduck.core.shared.DefaultTouchFeature;
import java.text.MessageFormat;
import java.util.Optional;
import ch.iterate.openstack.swift.model.StorageObject;
@@ -35,7 +36,7 @@ public class SwiftTouchFeature extends DefaultTouchFeature<StorageObject> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
// Creating files is only possible inside a container.
if(workdir.isRoot()) {
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename)).withFile(workdir);
@@ -8,11 +8,11 @@ import ch.cyberduck.core.SimplePathPredicate;
import ch.cyberduck.core.transfer.TransferStatus;
import ch.cyberduck.test.IntegrationTest;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import java.util.EnumSet;
import java.util.Optional;
import static org.junit.Assert.*;
@@ -21,8 +21,8 @@ public class SwiftTouchFeatureTest extends AbstractSwiftTest {
@Test
public void testSupported() {
assertFalse(new SwiftTouchFeature(session, new SwiftRegionService(session)).isSupported(new Path("/", EnumSet.of(Path.Type.directory, Path.Type.volume)), StringUtils.EMPTY));
assertTrue(new SwiftTouchFeature(session, new SwiftRegionService(session)).isSupported(new Path("/container", EnumSet.of(Path.Type.directory, Path.Type.volume)), StringUtils.EMPTY));
assertFalse(new SwiftTouchFeature(session, new SwiftRegionService(session)).isSupported(new Path("/", EnumSet.of(Path.Type.directory, Path.Type.volume)), Optional.empty()));
assertTrue(new SwiftTouchFeature(session, new SwiftRegionService(session)).isSupported(new Path("/container", EnumSet.of(Path.Type.directory, Path.Type.volume)), Optional.empty()));
}
@Test
@@ -2727,8 +2727,7 @@ public class BrowserController extends WindowController implements NSToolbar.Del
uploadPanel = NSOpenPanel.openPanel();
uploadPanel.setCanChooseDirectories(true);
uploadPanel.setCanChooseFiles(pool.getFeature(Touch.class).isSupported(
new UploadTargetFinder(workdir).find(this.getSelectedPath()),
StringUtils.EMPTY));
new UploadTargetFinder(workdir).find(this.getSelectedPath()), Optional.empty()));
uploadPanel.setCanCreateDirectories(false);
uploadPanel.setTreatsFilePackagesAsDirectories(true);
uploadPanel.setAllowsMultipleSelection(true);
@@ -470,7 +470,7 @@ public abstract class BrowserTableDataSource extends ProxyController implements
return NSDraggingInfo.NSDragOperationNone;
}
final Touch feature = controller.getSession().getFeature(Touch.class);
if(!feature.isSupported(destination, StringUtils.EMPTY)) {
if(!feature.isSupported(destination, Optional.empty())) {
// Target file system does not support creating files. Creating files is not supported
// for example in root of cloud storage accounts.
return NSDraggingInfo.NSDragOperationNone;
@@ -45,7 +45,6 @@ import ch.cyberduck.core.vault.VaultRegistry;
import ch.cyberduck.ui.browser.UploadTargetFinder;
import ch.cyberduck.ui.cocoa.controller.BrowserController;
import org.apache.commons.lang3.StringUtils;
import org.rococoa.Foundation;
import org.rococoa.Rococoa;
import org.rococoa.Selector;
@@ -236,25 +235,25 @@ public class BrowserToolbarValidator implements ToolbarValidator {
else if(action.equals(newfolder.action())) {
return this.isBrowser() && controller.isMounted() &&
controller.getSession().getFeature(Directory.class).isSupported(
new UploadTargetFinder(controller.workdir()).find(controller.getSelectedPath()), StringUtils.EMPTY
new UploadTargetFinder(controller.workdir()).find(controller.getSelectedPath()), Optional.empty()
);
}
else if(action.equals(Foundation.selector("createEncryptedVaultButtonClicked:"))) {
return this.isBrowser() && controller.isMounted() && controller.getSession().getVaultRegistry() != VaultRegistry.DISABLED &&
!controller.getSession().getVaultRegistry().contains(controller.workdir()) &&
controller.getSession().getFeature(Directory.class).isSupported(
new UploadTargetFinder(controller.workdir()).find(controller.getSelectedPath()), StringUtils.EMPTY
new UploadTargetFinder(controller.workdir()).find(controller.getSelectedPath()), Optional.empty()
);
}
else if(action.equals(Foundation.selector("createFileButtonClicked:"))) {
return this.isBrowser() && controller.isMounted() && controller.getSession().getFeature(Touch.class).isSupported(
new UploadTargetFinder(controller.workdir()).find(controller.getSelectedPath()), StringUtils.EMPTY
new UploadTargetFinder(controller.workdir()).find(controller.getSelectedPath()), Optional.empty()
);
}
else if(action.equals(upload.action())) {
return this.isBrowser() && controller.isMounted() && controller.getSession().getFeature(Touch.class).isSupported(
new UploadTargetFinder(controller.workdir()).find(controller.getSelectedPath()),
StringUtils.EMPTY);
Optional.empty());
}
else if(action.equals(Foundation.selector("createSymlinkButtonClicked:"))) {
return this.isBrowser() && controller.isMounted() && controller.getSession().getFeature(Symlink.class) != null
@@ -33,6 +33,7 @@ import org.jets3t.service.utils.ServiceUtils;
import java.text.MessageFormat;
import java.util.EnumSet;
import java.util.Optional;
public class S3DirectoryFeature implements Directory<StorageObject> {
@@ -69,11 +70,11 @@ public class S3DirectoryFeature implements Directory<StorageObject> {
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(StringUtils.isEmpty(RequestEntityRestStorageService.findBucketInHostname(session.getHost()))) {
if(workdir.isRoot()) {
if(StringUtils.isNotBlank(filename)) {
if(!ServiceUtils.isBucketNameValidDNSName(filename)) {
if(filename.isPresent()) {
if(!ServiceUtils.isBucketNameValidDNSName(filename.get())) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename));
}
}
@@ -31,6 +31,7 @@ import org.apache.commons.lang3.StringUtils;
import org.jets3t.service.model.StorageObject;
import java.text.MessageFormat;
import java.util.Optional;
public class S3TouchFeature extends DefaultTouchFeature<StorageObject> {
@@ -47,7 +48,7 @@ public class S3TouchFeature extends DefaultTouchFeature<StorageObject> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(StringUtils.isEmpty(RequestEntityRestStorageService.findBucketInHostname(session.getHost()))) {
// Creating files is only possible inside a bucket.
if(workdir.isRoot()) {
@@ -39,6 +39,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.junit.Assert.*;
@@ -59,7 +60,7 @@ public class S3DirectoryFeatureTest extends AbstractS3Test {
break;
default:
final Path test = new Path(new DefaultHomeFinderService(session).find(), new AsciiRandomStringService(30).random(), EnumSet.of(Path.Type.directory, Path.Type.volume));
assertTrue(feature.isSupported(test.getParent(), test.getName()));
assertTrue(feature.isSupported(test.getParent(), Optional.of(test.getName())));
test.attributes().setRegion(region.getIdentifier());
feature.mkdir(new S3WriteFeature(session, new S3AccessControlListFeature(session)), test, new TransferStatus().setRegion(region.getIdentifier()));
assertTrue(new S3FindFeature(session, acl).find(test));
@@ -92,7 +93,7 @@ public class S3DirectoryFeatureTest extends AbstractS3Test {
final S3DirectoryFeature feature = new S3DirectoryFeature(session, acl);
for(Location.Name region : Collections.singletonList(new S3LocationFeature.S3Region("us-east-1"))) {
final Path test = new Path(new DefaultHomeFinderService(session).find(), new AsciiRandomStringService(30).random(), EnumSet.of(Path.Type.directory, Path.Type.volume));
assertTrue(feature.isSupported(test.getParent(), test.getName()));
assertTrue(feature.isSupported(test.getParent(), Optional.of(test.getName())));
test.attributes().setRegion(region.getIdentifier());
feature.mkdir(new S3WriteFeature(session, new S3AccessControlListFeature(session)), test, new TransferStatus().setRegion(region.getIdentifier()));
assertTrue(new S3FindFeature(session, acl).find(test));
@@ -125,7 +126,7 @@ public class S3DirectoryFeatureTest extends AbstractS3Test {
final S3DirectoryFeature feature = new S3DirectoryFeature(session, acl);
for(Location.Name region : Collections.singletonList(new S3LocationFeature.S3Region("us-east-1"))) {
final Path test = new Path(new DefaultHomeFinderService(session).find(), new AsciiRandomStringService(30).random(), EnumSet.of(Path.Type.directory, Path.Type.volume));
assertTrue(feature.isSupported(test.getParent(), test.getName()));
assertTrue(feature.isSupported(test.getParent(), Optional.of(test.getName())));
test.attributes().setRegion(region.getIdentifier());
feature.mkdir(new S3WriteFeature(session, new S3AccessControlListFeature(session)), test, new TransferStatus().setRegion(region.getIdentifier()));
assertTrue(new S3FindFeature(session, acl).find(test));
@@ -139,8 +140,8 @@ public class S3DirectoryFeatureTest extends AbstractS3Test {
public void testCreateBucketInvalidName() throws Exception {
final S3AccessControlListFeature acl = new S3AccessControlListFeature(session);
final Path test = new Path(new DefaultHomeFinderService(session).find(), "untitled folder", EnumSet.of(Path.Type.directory, Path.Type.volume));
assertFalse(new S3DirectoryFeature(session, acl).isSupported(test.getParent(), test.getName()));
assertTrue(new S3DirectoryFeature(virtualhost, acl).isSupported(test.getParent(), test.getName()));
assertFalse(new S3DirectoryFeature(session, acl).isSupported(test.getParent(), Optional.of(test.getName())));
assertTrue(new S3DirectoryFeature(virtualhost, acl).isSupported(test.getParent(), Optional.of(test.getName())));
final S3LocationFeature.S3Region region = new S3LocationFeature.S3Region("eu-west-2");
test.attributes().setRegion(region.getIdentifier());
new S3DirectoryFeature(session, acl).mkdir(new S3WriteFeature(session, new S3AccessControlListFeature(session)), test, new TransferStatus().setRegion(region.getIdentifier()));
@@ -14,12 +14,12 @@ import ch.cyberduck.core.shared.DefaultFindFeature;
import ch.cyberduck.core.transfer.TransferStatus;
import ch.cyberduck.test.IntegrationTest;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Optional;
import static org.junit.Assert.*;
@@ -29,10 +29,10 @@ public class S3TouchFeatureTest extends AbstractS3Test {
@Test
public void testFile() {
final S3AccessControlListFeature acl = new S3AccessControlListFeature(session);
assertFalse(new S3TouchFeature(session, acl).isSupported(Home.root(), StringUtils.EMPTY));
assertTrue(new S3TouchFeature(session, acl).isSupported(new Path(Home.root(), "/container", EnumSet.of(Path.Type.volume, Path.Type.directory)), StringUtils.EMPTY));
assertTrue(new S3TouchFeature(virtualhost, acl).isSupported(Home.root(), StringUtils.EMPTY));
assertTrue(new S3TouchFeature(virtualhost, acl).isSupported(new Path(Home.root(), "/container", EnumSet.of(Path.Type.volume, Path.Type.directory)), StringUtils.EMPTY));
assertFalse(new S3TouchFeature(session, acl).isSupported(Home.root(), Optional.empty()));
assertTrue(new S3TouchFeature(session, acl).isSupported(new Path(Home.root(), "/container", EnumSet.of(Path.Type.volume, Path.Type.directory)), Optional.empty()));
assertTrue(new S3TouchFeature(virtualhost, acl).isSupported(Home.root(), Optional.empty()));
assertTrue(new S3TouchFeature(virtualhost, acl).isSupported(new Path(Home.root(), "/container", EnumSet.of(Path.Type.volume, Path.Type.directory)), Optional.empty()));
}
@Test
@@ -41,8 +41,8 @@ public class S3TouchFeatureTest extends AbstractS3Test {
final S3AccessControlListFeature acl = new S3AccessControlListFeature(session);
final S3TouchFeature feature = new S3TouchFeature(session, acl);
final String filename = new AsciiRandomStringService().random();
assertFalse(feature.isSupported(Home.root(), filename));
assertTrue(feature.isSupported(container, filename));
assertFalse(feature.isSupported(Home.root(), Optional.of(filename)));
assertTrue(feature.isSupported(container, Optional.of(filename)));
final Path test = feature.touch(new S3WriteFeature(session, new S3AccessControlListFeature(session)), new Path(container, filename, EnumSet.of(Path.Type.file)), new TransferStatus());
assertNull(test.attributes().getVersionId());
assertTrue(new S3FindFeature(session, acl).find(test));
@@ -57,7 +57,7 @@ public class S3TouchFeatureTest extends AbstractS3Test {
final S3AccessControlListFeature acl = new S3AccessControlListFeature(virtualhost);
final S3TouchFeature feature = new S3TouchFeature(virtualhost, acl);
final String filename = new AsciiRandomStringService().random();
assertTrue(feature.isSupported(Home.root(), filename));
assertTrue(feature.isSupported(Home.root(), Optional.of(filename)));
final Path test = feature.touch(new S3WriteFeature(virtualhost, new S3AccessControlListFeature(virtualhost)), new Path(filename, EnumSet.of(Path.Type.file)), new TransferStatus());
assertNull(test.attributes().getVersionId());
assertTrue(new S3FindFeature(virtualhost, acl).find(test));
@@ -29,6 +29,7 @@ import org.jets3t.service.model.StorageObject;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.Optional;
public class SpectraTouchFeature extends DefaultTouchFeature<StorageObject> {
@@ -47,7 +48,7 @@ public class SpectraTouchFeature extends DefaultTouchFeature<StorageObject> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
// Creating files is only possible inside a bucket.
if(workdir.isRoot()) {
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename)).withFile(workdir);
@@ -22,12 +22,12 @@ import ch.cyberduck.core.features.Home;
import ch.cyberduck.core.transfer.TransferStatus;
import ch.cyberduck.test.IntegrationTest;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Optional;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -37,8 +37,8 @@ public class SpectraTouchFeatureTest extends AbstractSpectraTest {
@Test
public void testFile() {
assertFalse(new SpectraTouchFeature(session).isSupported(Home.root(), StringUtils.EMPTY));
assertTrue(new SpectraTouchFeature(session).isSupported(new Path(Home.root(), "/container", EnumSet.of(Path.Type.directory, Path.Type.volume)), StringUtils.EMPTY));
assertFalse(new SpectraTouchFeature(session).isSupported(Home.root(), Optional.empty()));
assertTrue(new SpectraTouchFeature(session).isSupported(new Path(Home.root(), "/container", EnumSet.of(Path.Type.directory, Path.Type.volume)), Optional.empty()));
}
@Test
@@ -28,6 +28,7 @@ import ch.cyberduck.core.storegate.io.swagger.client.model.File;
import ch.cyberduck.core.transfer.TransferStatus;
import java.text.MessageFormat;
import java.util.Optional;
public class StoregateDirectoryFeature implements Directory<File> {
@@ -56,7 +57,7 @@ public class StoregateDirectoryFeature implements Directory<File> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(workdir.isRoot()) {
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString("Cannot create folder {0}", "Error"), filename)).withFile(workdir);
}
@@ -23,6 +23,7 @@ import ch.cyberduck.core.shared.DefaultTouchFeature;
import ch.cyberduck.core.storegate.io.swagger.client.model.File;
import java.text.MessageFormat;
import java.util.Optional;
public class StoregateTouchFeature extends DefaultTouchFeature<File> {
@@ -31,7 +32,7 @@ public class StoregateTouchFeature extends DefaultTouchFeature<File> {
}
@Override
public void preflight(final Path workdir, final String filename) throws BackgroundException {
public void preflight(final Path workdir, final Optional<String> filename) throws BackgroundException {
if(workdir.isRoot()) {
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), filename)).withFile(workdir);
}
@@ -1014,7 +1014,7 @@ namespace Ch.Cyberduck.Ui.Controller
return;
}
Touch feature = (Touch)Pool.getFeature(typeof(Touch));
if (!feature.isSupported(destination, String.Empty))
if (!feature.isSupported(destination, Optional.empty()))
{
args.Effect = DragDropEffects.None;
args.DropTargetLocation = DropTargetLocation.None;
@@ -1885,14 +1885,14 @@ namespace Ch.Cyberduck.Ui.Controller
{
return IsMounted() &&
((Touch)Pool.getFeature(typeof(Touch))).isSupported(
new UploadTargetFinder(Workdir).find(SelectedPath), String.Empty);
new UploadTargetFinder(Workdir).find(SelectedPath), Optional.empty());
}
private bool View_ValidateUpload()
{
return IsMounted() &&
((Touch)Pool.getFeature(typeof(Touch))).isSupported(
new UploadTargetFinder(Workdir).find(SelectedPath), String.Empty);
new UploadTargetFinder(Workdir).find(SelectedPath), Optional.empty());
}
private void View_Upload()
@@ -2061,7 +2061,7 @@ namespace Ch.Cyberduck.Ui.Controller
{
return IsMounted() &&
((Directory)Pool.getFeature(typeof(Directory))).isSupported(
new UploadTargetFinder(Workdir).find(SelectedPath), String.Empty);
new UploadTargetFinder(Workdir).find(SelectedPath), Optional.empty());
}
private bool View_ValidateNewVault()
@@ -2069,7 +2069,7 @@ namespace Ch.Cyberduck.Ui.Controller
return IsMounted() && Pool.getVaultRegistry() != VaultRegistry.DISABLED &&
!Pool.getVaultRegistry().contains(Workdir) &&
((Directory)Pool.getFeature(typeof(Directory))).isSupported(
new UploadTargetFinder(Workdir).find(SelectedPath), String.Empty);
new UploadTargetFinder(Workdir).find(SelectedPath), Optional.empty());
}
private void View_DuplicateFile()
@@ -2263,7 +2263,7 @@ namespace Ch.Cyberduck.Ui.Controller
return;
}
Touch feature = (Touch)Pool.getFeature(typeof(Touch));
if (!feature.isSupported(destination, String.Empty))
if (!feature.isSupported(destination, Optional.empty()))
{
Log.trace("Pool does not allow file creation");
args.Effect = DragDropEffects.None;