Skip to content

Commit

Permalink
Merge pull request #16701 from iterate-ch/bugfix/GH-16695
Browse files Browse the repository at this point in the history
Make target path for validation optional.
  • Loading branch information
dkocher authored Dec 23, 2024
2 parents 3144fde + 45e615a commit 2267828
Show file tree
Hide file tree
Showing 81 changed files with 644 additions and 430 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.text.MessageFormat;
import java.util.Optional;

import com.microsoft.azure.storage.AccessCondition;
import com.microsoft.azure.storage.OperationContext;
Expand Down Expand Up @@ -84,12 +85,14 @@ public Path copy(final Path source, final Path copy, final TransferStatus status
}

@Override
public void preflight(final Path source, final Path target) throws BackgroundException {
public void preflight(final Path source, final Optional<Path> target) throws BackgroundException {
if(containerService.isContainer(source)) {
throw new UnsupportedException(MessageFormat.format(LocaleFactory.localizedString("Cannot copy {0}", "Error"), source.getName())).withFile(source);
}
if(containerService.isContainer(target)) {
throw new UnsupportedException(MessageFormat.format(LocaleFactory.localizedString("Cannot copy {0}", "Error"), source.getName())).withFile(source);
if(target.isPresent()) {
if(containerService.isContainer(target.get())) {
throw new UnsupportedException(MessageFormat.format(LocaleFactory.localizedString("Cannot copy {0}", "Error"), source.getName())).withFile(source);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import ch.cyberduck.core.transfer.TransferStatus;

import java.util.Collections;
import java.util.Optional;

import com.microsoft.azure.storage.OperationContext;

Expand All @@ -41,7 +42,7 @@ public AzureMoveFeature(final AzureSession session, final OperationContext conte
}

@Override
public void preflight(final Path source, final Path target) throws BackgroundException {
public void preflight(final Path source, final Optional<Path> target) throws BackgroundException {
proxy.preflight(source, target);
delete.preflight(source);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.io.OutputStream;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.Optional;

import static org.junit.Assert.*;

Expand All @@ -34,9 +35,9 @@ public void testCopy() throws Exception {
new Path(container, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)), new TransferStatus());
Thread.sleep(1000L);
final AzureCopyFeature feature = new AzureCopyFeature(session, null);
assertThrows(UnsupportedException.class, () -> feature.preflight(container, test));
assertThrows(UnsupportedException.class, () -> feature.preflight(container, Optional.of(test)));
try {
feature.preflight(container, test);
feature.preflight(container, Optional.of(test));
}
catch(UnsupportedException e) {
assertEquals("Unsupported", e.getMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import java.util.Collections;
import java.util.EnumSet;
import java.util.Optional;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
Expand All @@ -36,8 +37,8 @@ public void testMove() throws Exception {
@Test
public void testSupport() {
final Path c = new Path("/c", EnumSet.of(Path.Type.directory));
assertFalse(new AzureMoveFeature(session, null).isSupported(c, c));
assertFalse(new AzureMoveFeature(session, null).isSupported(c, Optional.of(new Path("/d", EnumSet.of(Path.Type.directory)))));
final Path cf = new Path("/c/f", EnumSet.of(Path.Type.directory));
assertTrue(new AzureMoveFeature(session, null).isSupported(cf, cf));
assertTrue(new AzureMoveFeature(session, null).isSupported(cf, Optional.of(new Path("/c/f2", EnumSet.of(Path.Type.directory)))));
}
}
15 changes: 9 additions & 6 deletions backblaze/src/main/java/ch/cyberduck/core/b2/B2CopyFeature.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

import java.io.IOException;
import java.text.MessageFormat;
import java.util.Optional;

import synapticloop.b2.exception.B2ApiException;
import synapticloop.b2.response.B2FileResponse;
Expand Down Expand Up @@ -65,18 +66,20 @@ public Path copy(final Path source, final Path target, final TransferStatus stat
}

@Override
public void preflight(final Path source, final Path target) throws BackgroundException {
public void preflight(final Path source, final Optional<Path> target) throws BackgroundException {
if(source.getType().contains(Path.Type.upload)) {
throw new UnsupportedException(MessageFormat.format(LocaleFactory.localizedString("Cannot copy {0}", "Error"), source.getName())).withFile(source);
}
if(containerService.isContainer(source)) {
throw new UnsupportedException(MessageFormat.format(LocaleFactory.localizedString("Cannot copy {0}", "Error"), source.getName())).withFile(source);
}
if(containerService.isContainer(target)) {
throw new UnsupportedException(MessageFormat.format(LocaleFactory.localizedString("Cannot copy {0}", "Error"), source.getName())).withFile(source);
}
if(!new SimplePathPredicate(containerService.getContainer(source)).test(containerService.getContainer(target))) {
throw new UnsupportedException(MessageFormat.format(LocaleFactory.localizedString("Cannot copy {0}", "Error"), source.getName())).withFile(source);
if(target.isPresent()) {
if(containerService.isContainer(target.get())) {
throw new UnsupportedException(MessageFormat.format(LocaleFactory.localizedString("Cannot copy {0}", "Error"), source.getName())).withFile(source);
}
if(!new SimplePathPredicate(containerService.getContainer(source)).test(containerService.getContainer(target.get()))) {
throw new UnsupportedException(MessageFormat.format(LocaleFactory.localizedString("Cannot copy {0}", "Error"), source.getName())).withFile(source);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@
import java.text.MessageFormat;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Optional;

public class B2MoveFeature implements Move {

private final PathContainerService containerService
= new B2PathContainerService();
= new B2PathContainerService();

private final B2Session session;
private final B2VersionIdProvider fileid;
Expand All @@ -54,7 +55,7 @@ public Path move(final Path source, final Path target, final TransferStatus stat
}

@Override
public void preflight(final Path source, final Path target) throws BackgroundException {
public void preflight(final Path source, final Optional<Path> target) throws BackgroundException {
if(containerService.isContainer(source)) {
throw new UnsupportedException(MessageFormat.format(LocaleFactory.localizedString("Cannot rename {0}", "Error"), source.getName())).withFile(source);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import ch.cyberduck.core.transfer.TransferStatus;

import java.util.EnumSet;
import java.util.Optional;

public class B2ThresholdCopyFeature implements Copy {

Expand Down Expand Up @@ -52,7 +53,7 @@ public Path copy(final Path source, final Path target, final TransferStatus stat
}

@Override
public void preflight(final Path source, final Path target) throws BackgroundException {
public void preflight(final Path source, final Optional<Path> target) throws BackgroundException {
new B2CopyFeature(session, fileid).preflight(source, target);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

import java.util.Arrays;
import java.util.EnumSet;
import java.util.Optional;

import static org.junit.Assert.*;

Expand All @@ -46,9 +47,9 @@ public void testCopy() throws Exception {
final Path test = new B2TouchFeature(session, fileid).touch(new Path(container, name, EnumSet.of(Path.Type.file)), new TransferStatus());
assertTrue(new B2FindFeature(session, fileid).find(test));
final B2CopyFeature feature = new B2CopyFeature(session, fileid);
assertThrows(UnsupportedException.class, () -> feature.preflight(container, test));
assertThrows(UnsupportedException.class, () -> feature.preflight(container, Optional.of(test)));
try {
feature.preflight(container, test);
feature.preflight(container, Optional.of(test));
}
catch(UnsupportedException e) {
assertEquals("Unsupported", e.getMessage());
Expand Down
12 changes: 8 additions & 4 deletions box/src/main/java/ch/cyberduck/core/box/BoxCopyFeature.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import java.text.MessageFormat;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Optional;

import static ch.cyberduck.core.features.Copy.validate;

Expand Down Expand Up @@ -87,10 +88,13 @@ public EnumSet<Flags> features(final Path source, final Path target) {
}

@Override
public void preflight(final Path source, final Path target) throws BackgroundException {
if(!BoxTouchFeature.validate(target.getName())) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), target.getName()));
public void preflight(final Path source, final Optional<Path> optional) throws BackgroundException {
if(optional.isPresent()) {
final Path target = optional.get();
if(!BoxTouchFeature.validate(target.getName())) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), target.getName()));
}
validate(session.getCaseSensitivity(), source, target);
}
validate(session.getCaseSensitivity(), source, target);
}
}
10 changes: 7 additions & 3 deletions box/src/main/java/ch/cyberduck/core/box/BoxMoveFeature.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import java.text.MessageFormat;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Optional;

public class BoxMoveFeature implements Move {
private static final Logger log = LogManager.getLogger(BoxMoveFeature.class);
Expand Down Expand Up @@ -93,9 +94,12 @@ public EnumSet<Flags> features(final Path source, final Path target) {
}

@Override
public void preflight(final Path source, final Path target) throws BackgroundException {
if(!BoxTouchFeature.validate(target.getName())) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), target.getName())).withFile(source);
public void preflight(final Path source, final Optional<Path> optional) throws BackgroundException {
if(optional.isPresent()) {
final Path target = optional.get();
if(!BoxTouchFeature.validate(target.getName())) {
throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), target.getName())).withFile(source);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

import java.util.Collections;
import java.util.EnumSet;
import java.util.Optional;

import static ch.cyberduck.core.features.Copy.validate;

Expand All @@ -54,8 +55,8 @@ public Path copy(final Path file, final Path target, final TransferStatus status
new BrickDeleteFeature(session).delete(Collections.singletonList(target), callback, new Delete.DisabledCallback());
}
final FileActionEntity entity = new FileActionsApi(client)
.copy(new CopyPathBody().destination(StringUtils.removeStart(target.getAbsolute(), String.valueOf(Path.DELIMITER))),
StringUtils.removeStart(file.getAbsolute(), String.valueOf(Path.DELIMITER)));
.copy(new CopyPathBody().destination(StringUtils.removeStart(target.getAbsolute(), String.valueOf(Path.DELIMITER))),
StringUtils.removeStart(file.getAbsolute(), String.valueOf(Path.DELIMITER)));
listener.sent(status.getLength());
if(entity.getFileMigrationId() != null) {
this.poll(client, entity);
Expand All @@ -73,8 +74,10 @@ public EnumSet<Flags> features(final Path source, final Path target) {
}

@Override
public void preflight(final Path source, final Path target) throws BackgroundException {
public void preflight(final Path source, final Optional<Path> target) throws BackgroundException {
Copy.super.preflight(source, target);
validate(session.getCaseSensitivity(), source, target);
if(target.isPresent()) {
validate(session.getCaseSensitivity(), source, target.get());
}
}
}
15 changes: 9 additions & 6 deletions core/src/main/java/ch/cyberduck/core/features/Copy.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ default boolean isRecursive(final Path source, final Path target) {
* @param target Target file or folder
* @return False if not supported for given files
*/
default boolean isSupported(final Path source, final Path target) {
default boolean isSupported(final Path source, final java.util.Optional<Path> target) {
try {
this.preflight(source, target);
return true;
Expand All @@ -84,12 +84,15 @@ default Copy withTarget(final Session<?> session) {
* @throws UnsupportedException Copy operation not supported for source
* @throws InvalidFilenameException Target filename not supported
*/
default void preflight(final Path source, final Path target) throws BackgroundException {
if(!target.getParent().attributes().getPermission().isWritable()) {
throw new UnsupportedException(MessageFormat.format(LocaleFactory.localizedString("Cannot copy {0}", "Error"),
source.getName())).withFile(source);
default void preflight(final Path source, final java.util.Optional<Path> optional) throws BackgroundException {
if(optional.isPresent()) {
final Path target = optional.get();
if(!target.getParent().attributes().getPermission().isWritable()) {
throw new UnsupportedException(MessageFormat.format(LocaleFactory.localizedString("Cannot copy {0}", "Error"),
source.getName())).withFile(source);
}
validate(Protocol.Case.sensitive, source, target);
}
validate(Protocol.Case.sensitive, source, target);
}

/**
Expand Down
23 changes: 13 additions & 10 deletions core/src/main/java/ch/cyberduck/core/features/Move.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import java.text.MessageFormat;
import java.util.EnumSet;
import java.util.Optional;

/**
* Move or rename file or folder on server
Expand Down Expand Up @@ -58,7 +59,7 @@ default boolean isRecursive(final Path source, final Path target) {
* @param target Target file or folder
* @return False if not supported for given files
*/
default boolean isSupported(final Path source, final Path target) {
default boolean isSupported(final Path source, final java.util.Optional<Path> target) {
try {
this.preflight(source, target);
return true;
Expand All @@ -81,15 +82,17 @@ default Move withTarget(Session<?> session) {
* @throws UnsupportedException Move operation not supported for source
* @throws InvalidFilenameException Target filename not supported
*/
default void preflight(final Path source, final Path target) throws BackgroundException {
if(!target.getParent().attributes().getPermission().isWritable()) {
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString("Cannot rename {0}", "Error"),
source.getName())).withFile(source);
}
// Deny move to self
if(new SimplePathPredicate(source).test(target)) {
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString("Cannot rename {0}", "Error"),
source.getName())).withFile(source);
default void preflight(final Path source, final Optional<Path> target) throws BackgroundException {
if(target.isPresent()) {
if(!target.get().getParent().attributes().getPermission().isWritable()) {
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString("Cannot rename {0}", "Error"),
source.getName())).withFile(source);
}
// Deny move to self
if(new SimplePathPredicate(source).test(target.get())) {
throw new AccessDeniedException(MessageFormat.format(LocaleFactory.localizedString("Cannot rename {0}", "Error"),
source.getName())).withFile(source);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.Objects;
import java.util.Optional;

public class DefaultCopyFeature implements Copy {
private static final Logger log = LogManager.getLogger(DefaultCopyFeature.class);
Expand Down Expand Up @@ -70,7 +71,7 @@ public Path copy(final Path source, final Path target, final TransferStatus stat
}

@Override
public void preflight(final Path source, final Path target) throws BackgroundException {
public void preflight(final Path source, final Optional<Path> target) throws BackgroundException {
switch(from.getHost().getProtocol().getType()) {
case ftp:
case irods:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import java.util.Date;
import java.util.EnumSet;
import java.util.List;
import java.util.Optional;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -96,7 +97,7 @@ public void setConfiguration(final Path container, final PasswordCallback prompt
public boolean save(final Path file) throws BackgroundException {
final Path version = new Path(provider.provide(file), formatter.toVersion(file.getName()), file.getType());
final Move feature = session.getFeature(Move.class);
if(!feature.isSupported(file, version)) {
if(!feature.isSupported(file, Optional.of(version))) {
log.warn("Skip saving version for {}", file);
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import ch.cyberduck.core.features.Move;
import ch.cyberduck.core.transfer.TransferStatus;

import java.util.Optional;

public class DisabledMoveFeature implements Move {

@Override
Expand All @@ -36,7 +38,7 @@ public Path move(final Path file, final Path renamed, final TransferStatus statu
}

@Override
public void preflight(final Path source, final Path target) throws BackgroundException {
public void preflight(final Path source, final Optional<Path> target) throws BackgroundException {
throw new AccessDeniedException(LocaleFactory.localizedString("Unsupported", "Error"));
}
}
Loading

0 comments on commit 2267828

Please sign in to comment.