Skip to content

Commit 35d483b

Browse files
Merge branch 'release/1.9.4'
2 parents 3accfd2 + b635d5c commit 35d483b

18 files changed

+322
-142
lines changed

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ env:
88
- secure: "LT4nMSKCu4qL+jQ80BdBIOqFO3GCyAPoxNkskS0q0wvscDpEx2bvFZa9KF6/dQxubhWnfACqWxxPKfF3VadfZoKn1z01TaZ/rKHkA5GedZweFO0wBIvi/gDIcAxVX0oPOkIruugYY3iDOzOqTUuBM686cW1XWs0LEV7qPTb6KM02/IeckQs+P9SSiarqSKROlQ8dABGdyxJTXheHHphFu4mDiQsi1vtub6OoQclKLLuK2MJvFiyDeZDYYXAnjFNC/pcBUBjr5b886zPB6HLLGgvQKRLvzQudedz08ZlJdnt3k6u7HvLINbs00U60fnD/+4krQQN4EEx0Natv4L1SxFjYO4wFK2FTCKoBMkVfjINqiWzmb/yhoG33Sw9VGiYdcV45QbH32CX1oiATohV+79gfIID6p3UOL1SZuELR2XzRq70K4Kw2BXig99a0+LjYCv4ynnzetqyWVZIdhBQ1Srf/4GxUwF21Urn9TJCNr2F5BcbqGrMUMvXNjTI0WqQCTMqM+Ha9Rbe27GG7ZMtMUHd83YWP0GDiSIg2S0T0lNL2e9iQGXsGBiX3Bz+E3HEWhnE4l6XKYVgn3NXrlDjwc2B6GTGeImZXkrbFFJwQihUSujj5H6l/+5a7NxbyA1MvzNwjeTaHzdNdYovTq6ywydVtF/Kt5h7oA2KmUoajaFs=" # CODACY_PROJECT_TOKEN
99
- secure: "atP4OKMKBLaixI1BiypWRxdQ1DJKpUcxQStwJpXteaZuXdkTMx31ts9WGhwwWJCjDaPJJRmWqhxTNKxJLThWFWLmBso1gHm8KDoHWBGM5jS1ua8Ly7s72HCpa7z+ABZ1/2LsoUXfQGLGDIPs1EdL/2E8OlaPSFUDFwgyquEIEm0hcKOO9q9MxjXwj8EO8OsfGt3PjiWEsh+JRaK5+hRPPVbG7TXidG84C/2cndzNSnin57LUSNkKDPoysRrQipGZQSLm12MpBagcota2HDdiuDXLHJLauNllCsr/NLnurGhwqeV3zVjPlN6z5TbZhbWvni+a8jVO9tMR3zCPs2MR++rJqXoQ4Gviy9yHQFc/RnVtCIRfCHhmh3XyhEM/Z5c1zEjhyZD1eGzr625/1F/RJLJEi0jb0kihKBpEKRgGw/ppt9BkdWQ4xJsMI8H9IQ5ZfzvRhLMXhbLDwqfyfyr3fX8pWg8T9lajEcDwnWMrYerAIF67lyQBjl3c3cGcGn909FTPGjum2PFSY7MuFfmbzzi41Y9ekssiRun4XrgNu563VtIywwuy/35N4ub1+oXS0I2PCG5XBY5uvxZbL8niqmoKiFFeyIhkMdGcbvIqA7PLapPqY5NxkY4+gRSP/eOMzMCnJv/No1ZaDV/8PW4/Q5IRxehVIIX/sXPiOvDSR58=" # BINTRAY_API_KEY
1010
install:
11-
- curl -o $HOME/.m2/settings.xml https://gist.githubusercontent.com/cryptobot/cf5fbd909c4782aaeeeb7c7f4a1a43da/raw/e60ee486e34ee0c79f89f947abe2c83b4290c6bb/settings.xml
11+
- curl -o $HOME/.m2/settings.xml https://gist.githubusercontent.com/cryptobot/cf5fbd909c4782aaeeeb7c7f4a1a43da/raw/fb3fe9a6db00cdac09788285b108a3645193a45b/settings.xml
1212
before_script:
1313
- mvn -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN --update-snapshots dependency-check:check -Pdependency-check
1414
- if [ -n "$TRAVIS_TAG" ]; then mvn versions:set -DnewVersion=${TRAVIS_TAG}; fi
@@ -22,7 +22,7 @@ script:
2222
mvn clean test jacoco:report verify -Pcoverage
2323
fi
2424
after_success:
25-
- curl -o ~/codacy-coverage-reporter.jar https://oss.sonatype.org/service/local/repositories/releases/content/com/codacy/codacy-coverage-reporter/6.0.7/codacy-coverage-reporter-6.0.7-assembly.jar
25+
- curl -o ~/codacy-coverage-reporter.jar https://repo1.maven.org/maven2/com/codacy/codacy-coverage-reporter/7.1.0/codacy-coverage-reporter-7.1.0.jar
2626
- $JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar report -l Java -r target/site/jacoco/jacoco.xml
2727
cache:
2828
directories:

pom.xml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<modelVersion>4.0.0</modelVersion>
33
<groupId>org.cryptomator</groupId>
44
<artifactId>cryptofs</artifactId>
5-
<version>1.9.3</version>
5+
<version>1.9.4</version>
66
<name>Cryptomator Crypto Filesystem</name>
77
<description>This library provides the Java filesystem provider used by Cryptomator.</description>
88
<url>https://github.com/cryptomator/cryptofs</url>
@@ -15,12 +15,12 @@
1515

1616
<properties>
1717
<cryptolib.version>1.3.0</cryptolib.version>
18-
<dagger.version>2.26</dagger.version>
18+
<dagger.version>2.27</dagger.version>
1919
<guava.version>28.2-jre</guava.version>
2020
<slf4j.version>1.7.30</slf4j.version>
2121

22-
<junit.jupiter.version>5.6.0</junit.jupiter.version>
23-
<mockito.version>3.2.4</mockito.version>
22+
<junit.jupiter.version>5.6.1</junit.jupiter.version>
23+
<mockito.version>3.3.3</mockito.version>
2424
<hamcrest.version>2.2</hamcrest.version>
2525
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
2626
</properties>
@@ -158,7 +158,7 @@
158158
<plugin>
159159
<groupId>org.owasp</groupId>
160160
<artifactId>dependency-check-maven</artifactId>
161-
<version>5.2.4</version>
161+
<version>5.3.1</version>
162162
<configuration>
163163
<cveValidForHours>24</cveValidForHours>
164164
<failBuildOnCVSS>0</failBuildOnCVSS>
@@ -229,7 +229,7 @@
229229
</plugin>
230230
<plugin>
231231
<artifactId>maven-javadoc-plugin</artifactId>
232-
<version>3.1.1</version>
232+
<version>3.2.0</version>
233233
<executions>
234234
<execution>
235235
<id>attach-javadocs</id>
@@ -275,7 +275,7 @@
275275
</plugin>
276276
<plugin>
277277
<artifactId>maven-dependency-plugin</artifactId>
278-
<version>3.1.1</version>
278+
<version>3.1.2</version>
279279
<executions>
280280
<execution>
281281
<id>generate-dependency-list</id>

src/main/java/org/cryptomator/cryptofs/CryptoFileSystemModule.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import dagger.Module;
99
import dagger.Provides;
10+
import org.cryptomator.cryptofs.attr.AttributeComponent;
1011
import org.cryptomator.cryptofs.attr.AttributeViewComponent;
1112
import org.cryptomator.cryptofs.common.Constants;
1213
import org.cryptomator.cryptofs.common.MasterkeyBackupFileHasher;
@@ -23,7 +24,7 @@
2324

2425
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
2526

26-
@Module(subcomponents = {AttributeViewComponent.class, OpenCryptoFileComponent.class, DirectoryStreamComponent.class})
27+
@Module(subcomponents = {AttributeComponent.class, AttributeViewComponent.class, OpenCryptoFileComponent.class, DirectoryStreamComponent.class})
2728
class CryptoFileSystemModule {
2829

2930
@Provides

src/main/java/org/cryptomator/cryptofs/Symlinks.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ private void assertIsSymlink(CryptoPath cleartextPath, Path ciphertextSymlinkFil
8888
}
8989
}
9090

91+
/**
92+
* Gets the target of a symlink. Recursive, if the target is a symlink itself.
93+
* @param cleartextPath A cleartext path. Might be a symlink, otherwise this method is no-op.
94+
* @return The resolved cleartext path. Might be the same as <code>cleartextPath</code> if it wasn't a symlink in the first place.
95+
* @throws IOException
96+
*/
9197
public CryptoPath resolveRecursively(CryptoPath cleartextPath) throws IOException {
9298
return resolveRecursively(new HashSet<>(), cleartextPath);
9399
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package org.cryptomator.cryptofs.attr;
2+
3+
import dagger.BindsInstance;
4+
import dagger.Subcomponent;
5+
import org.cryptomator.cryptofs.common.CiphertextFileType;
6+
7+
import java.nio.file.Path;
8+
import java.nio.file.attribute.BasicFileAttributes;
9+
import java.util.Optional;
10+
11+
@AttributeScoped
12+
@Subcomponent(modules = {AttributeModule.class})
13+
public interface AttributeComponent {
14+
15+
Optional<BasicFileAttributes> attributes();
16+
17+
@Subcomponent.Builder
18+
interface Builder {
19+
20+
@BindsInstance
21+
Builder type(Class<? extends BasicFileAttributes> type);
22+
23+
@BindsInstance
24+
Builder ciphertextPath(Path ciphertextPath);
25+
26+
@BindsInstance
27+
Builder ciphertextFileType(CiphertextFileType ciphertextFileType);
28+
29+
@BindsInstance
30+
Builder ciphertextAttributes(BasicFileAttributes ciphertextAttributes);
31+
32+
AttributeComponent build();
33+
}
34+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package org.cryptomator.cryptofs.attr;
2+
3+
import dagger.Binds;
4+
import dagger.Module;
5+
import dagger.Provides;
6+
import dagger.multibindings.ClassKey;
7+
import dagger.multibindings.IntoMap;
8+
import org.cryptomator.cryptofs.fh.OpenCryptoFile;
9+
import org.cryptomator.cryptofs.fh.OpenCryptoFiles;
10+
11+
import javax.inject.Provider;
12+
import java.nio.file.Path;
13+
import java.nio.file.attribute.BasicFileAttributes;
14+
import java.nio.file.attribute.DosFileAttributes;
15+
import java.nio.file.attribute.PosixFileAttributes;
16+
import java.util.Map;
17+
import java.util.Optional;
18+
19+
@Module
20+
abstract class AttributeModule {
21+
22+
@Provides
23+
@AttributeScoped
24+
public static Optional<OpenCryptoFile> provideOpenCryptoFile(OpenCryptoFiles openCryptoFiles, Path ciphertextPath) {
25+
return openCryptoFiles.get(ciphertextPath);
26+
}
27+
28+
@Provides
29+
@AttributeScoped
30+
public static PosixFileAttributes providePosixFileAttributes(BasicFileAttributes ciphertextAttributes) {
31+
if (ciphertextAttributes instanceof PosixFileAttributes) {
32+
return (PosixFileAttributes) ciphertextAttributes;
33+
} else {
34+
throw new IllegalStateException("Attempted to inject instance of type " + ciphertextAttributes.getClass() + " but expected PosixFileAttributes.");
35+
}
36+
}
37+
38+
@Provides
39+
@AttributeScoped
40+
public static DosFileAttributes provideDosFileAttributes(BasicFileAttributes ciphertextAttributes) {
41+
if (ciphertextAttributes instanceof DosFileAttributes) {
42+
return (DosFileAttributes) ciphertextAttributes;
43+
} else {
44+
throw new IllegalStateException("Attempted to inject instance of type " + ciphertextAttributes.getClass() + " but expected DosFileAttributes.");
45+
}
46+
}
47+
48+
@Binds
49+
@IntoMap
50+
@ClassKey(BasicFileAttributes.class)
51+
@AttributeScoped
52+
public abstract BasicFileAttributes bindCryptoBasicFileAttributes(CryptoBasicFileAttributes view);
53+
54+
@Binds
55+
@IntoMap
56+
@ClassKey(PosixFileAttributes.class)
57+
@AttributeScoped
58+
public abstract BasicFileAttributes bindCryptoPosixFileAttributes(CryptoPosixFileAttributes view);
59+
60+
@Binds
61+
@IntoMap
62+
@ClassKey(DosFileAttributes.class)
63+
@AttributeScoped
64+
public abstract BasicFileAttributes bindCryptoDosFileAttributes(CryptoDosFileAttributes view);
65+
66+
@Provides
67+
@AttributeScoped
68+
public static Optional<BasicFileAttributes> provideAttributes(Map<Class<?>, Provider<BasicFileAttributes>> providers, Class<? extends BasicFileAttributes> requestedType) {
69+
Provider<BasicFileAttributes> provider = providers.get(requestedType);
70+
if (provider == null) {
71+
return Optional.empty();
72+
} else {
73+
return Optional.of(provider.get());
74+
}
75+
}
76+
77+
}

src/main/java/org/cryptomator/cryptofs/attr/AttributeProvider.java

Lines changed: 33 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -8,94 +8,68 @@
88
*******************************************************************************/
99
package org.cryptomator.cryptofs.attr;
1010

11-
import org.cryptomator.cryptofs.common.ArrayUtils;
12-
import org.cryptomator.cryptofs.common.CiphertextFileType;
13-
import org.cryptomator.cryptofs.CryptoFileSystemProperties;
11+
import org.cryptomator.cryptofs.CryptoFileSystemScoped;
1412
import org.cryptomator.cryptofs.CryptoPath;
1513
import org.cryptomator.cryptofs.CryptoPathMapper;
16-
import org.cryptomator.cryptofs.fh.OpenCryptoFiles;
17-
import org.cryptomator.cryptofs.CryptoFileSystemScoped;
1814
import org.cryptomator.cryptofs.Symlinks;
19-
import org.cryptomator.cryptofs.fh.OpenCryptoFile;
20-
import org.cryptomator.cryptolib.api.Cryptor;
15+
import org.cryptomator.cryptofs.common.ArrayUtils;
16+
import org.cryptomator.cryptofs.common.CiphertextFileType;
2117

2218
import javax.inject.Inject;
2319
import java.io.IOException;
2420
import java.nio.file.Files;
2521
import java.nio.file.LinkOption;
2622
import java.nio.file.Path;
2723
import java.nio.file.attribute.BasicFileAttributes;
28-
import java.nio.file.attribute.DosFileAttributes;
29-
import java.nio.file.attribute.PosixFileAttributes;
30-
import java.util.HashMap;
31-
import java.util.Map;
3224
import java.util.Optional;
3325

3426
@CryptoFileSystemScoped
3527
public class AttributeProvider {
3628

37-
private static final Map<Class<? extends BasicFileAttributes>, AttributesConstructor<? extends BasicFileAttributes>> ATTR_CONSTRUCTORS;
38-
39-
static {
40-
ATTR_CONSTRUCTORS = new HashMap<>();
41-
ATTR_CONSTRUCTORS.put(BasicFileAttributes.class, (AttributesConstructor<BasicFileAttributes>) CryptoBasicFileAttributes::new);
42-
ATTR_CONSTRUCTORS.put(PosixFileAttributes.class, (AttributesConstructor<PosixFileAttributes>) CryptoPosixFileAttributes::new);
43-
ATTR_CONSTRUCTORS.put(DosFileAttributes.class, (AttributesConstructor<DosFileAttributes>) CryptoDosFileAttributes::new);
44-
}
45-
46-
private final Cryptor cryptor;
29+
private final AttributeComponent.Builder attributeComponentBuilder;
4730
private final CryptoPathMapper pathMapper;
48-
private final OpenCryptoFiles openCryptoFiles;
49-
private final CryptoFileSystemProperties fileSystemProperties;
5031
private final Symlinks symlinks;
5132

5233
@Inject
53-
AttributeProvider(Cryptor cryptor, CryptoPathMapper pathMapper, OpenCryptoFiles openCryptoFiles, CryptoFileSystemProperties fileSystemProperties, Symlinks symlinks) {
54-
this.cryptor = cryptor;
34+
AttributeProvider(AttributeComponent.Builder attributeComponentBuilder, CryptoPathMapper pathMapper, Symlinks symlinks) {
35+
this.attributeComponentBuilder = attributeComponentBuilder;
5536
this.pathMapper = pathMapper;
56-
this.openCryptoFiles = openCryptoFiles;
57-
this.fileSystemProperties = fileSystemProperties;
5837
this.symlinks = symlinks;
5938
}
6039

6140
public <A extends BasicFileAttributes> A readAttributes(CryptoPath cleartextPath, Class<A> type, LinkOption... options) throws IOException {
62-
if (!ATTR_CONSTRUCTORS.containsKey(type)) {
63-
throw new UnsupportedOperationException("Unsupported file attribute type: " + type);
64-
}
6541
CiphertextFileType ciphertextFileType = pathMapper.getCiphertextFileType(cleartextPath);
66-
switch (ciphertextFileType) {
67-
case SYMLINK: {
68-
if (ArrayUtils.contains(options, LinkOption.NOFOLLOW_LINKS)) {
69-
Path ciphertextPath = pathMapper.getCiphertextFilePath(cleartextPath).getSymlinkFilePath();
70-
return readAttributes(ciphertextFileType, ciphertextPath, type);
71-
} else {
72-
CryptoPath resolved = symlinks.resolveRecursively(cleartextPath);
73-
return readAttributes(resolved, type, options);
74-
}
75-
}
76-
case DIRECTORY: {
77-
Path ciphertextPath = pathMapper.getCiphertextDir(cleartextPath).path;
78-
return readAttributes(ciphertextFileType, ciphertextPath, type);
79-
}
80-
case FILE: {
81-
Path ciphertextPath = pathMapper.getCiphertextFilePath(cleartextPath).getFilePath();
82-
return readAttributes(ciphertextFileType, ciphertextPath, type);
83-
}
84-
default:
85-
throw new UnsupportedOperationException("Unhandled node type " + ciphertextFileType);
42+
if (ciphertextFileType == CiphertextFileType.SYMLINK && !ArrayUtils.contains(options, LinkOption.NOFOLLOW_LINKS)) {
43+
cleartextPath = symlinks.resolveRecursively(cleartextPath);
44+
ciphertextFileType = pathMapper.getCiphertextFileType(cleartextPath);
8645
}
87-
}
88-
89-
private <A extends BasicFileAttributes> A readAttributes(CiphertextFileType ciphertextFileType, Path ciphertextPath, Class<A> type) throws IOException {
90-
assert ATTR_CONSTRUCTORS.containsKey(type);
46+
Path ciphertextPath = getCiphertextPath(cleartextPath, ciphertextFileType);
9147
A ciphertextAttrs = Files.readAttributes(ciphertextPath, type);
92-
AttributesConstructor<A> constructor = (AttributesConstructor<A>) ATTR_CONSTRUCTORS.get(type);
93-
return constructor.construct(ciphertextAttrs, ciphertextFileType, ciphertextPath, cryptor, openCryptoFiles.get(ciphertextPath), fileSystemProperties.readonly());
48+
Optional<BasicFileAttributes> cleartextAttrs = attributeComponentBuilder //
49+
.type(type) //
50+
.ciphertextFileType(ciphertextFileType) //
51+
.ciphertextPath(ciphertextPath) //
52+
.ciphertextAttributes(ciphertextAttrs) //
53+
.build() //
54+
.attributes();
55+
if (cleartextAttrs.isPresent() && type.isInstance(cleartextAttrs.get())) {
56+
return type.cast(cleartextAttrs.get());
57+
} else {
58+
throw new UnsupportedOperationException("Unsupported file attribute type: " + type);
59+
}
9460
}
9561

96-
@FunctionalInterface
97-
private interface AttributesConstructor<A extends BasicFileAttributes> {
98-
A construct(A delegate, CiphertextFileType ciphertextFileType, Path ciphertextPath, Cryptor cryptor, Optional<OpenCryptoFile> openCryptoFile, boolean readonlyFileSystem);
62+
private Path getCiphertextPath(CryptoPath path, CiphertextFileType type) throws IOException {
63+
switch (type) {
64+
case SYMLINK:
65+
return pathMapper.getCiphertextFilePath(path).getSymlinkFilePath();
66+
case DIRECTORY:
67+
return pathMapper.getCiphertextDir(path).path;
68+
case FILE:
69+
return pathMapper.getCiphertextFilePath(path).getFilePath();
70+
default:
71+
throw new UnsupportedOperationException("Unhandled node type " + type);
72+
}
9973
}
10074

10175
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.cryptomator.cryptofs.attr;
2+
3+
import javax.inject.Scope;
4+
5+
import java.lang.annotation.Documented;
6+
import java.lang.annotation.Retention;
7+
8+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
9+
10+
@Scope
11+
@Documented
12+
@Retention(RUNTIME)
13+
@interface AttributeScoped {
14+
}

src/main/java/org/cryptomator/cryptofs/attr/AttributeViewScoped.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@
1010
@Scope
1111
@Documented
1212
@Retention(RUNTIME)
13-
public @interface AttributeViewScoped {
13+
@interface AttributeViewScoped {
1414
}

src/main/java/org/cryptomator/cryptofs/attr/CryptoBasicFileAttributes.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@
1515
import org.slf4j.Logger;
1616
import org.slf4j.LoggerFactory;
1717

18+
import javax.inject.Inject;
1819
import java.nio.file.Path;
1920
import java.nio.file.attribute.BasicFileAttributes;
2021
import java.nio.file.attribute.FileTime;
2122
import java.time.Instant;
2223
import java.util.Optional;
2324

25+
@AttributeScoped
2426
class CryptoBasicFileAttributes implements BasicFileAttributes {
2527

2628
private static final Logger LOG = LoggerFactory.getLogger(CryptoBasicFileAttributes.class);
@@ -32,7 +34,8 @@ class CryptoBasicFileAttributes implements BasicFileAttributes {
3234
private final FileTime creationTime;
3335
private final Object fileKey;
3436

35-
public CryptoBasicFileAttributes(BasicFileAttributes delegate, CiphertextFileType ciphertextFileType, Path ciphertextPath, Cryptor cryptor, Optional<OpenCryptoFile> openCryptoFile, @SuppressWarnings("unused") boolean readonlyFileSystem) {
37+
@Inject
38+
public CryptoBasicFileAttributes(BasicFileAttributes delegate, CiphertextFileType ciphertextFileType, Path ciphertextPath, Cryptor cryptor, Optional<OpenCryptoFile> openCryptoFile) {
3639
this.ciphertextFileType = ciphertextFileType;
3740
switch (ciphertextFileType) {
3841
case SYMLINK:

0 commit comments

Comments
 (0)