diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c2b928dc..9f706d7d 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,7 +6,7 @@ updates: interval: "weekly" day: "monday" time: "06:00" - timezone: "UTC" + timezone: "Etc/UTC" groups: java-test-dependencies: patterns: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fa25f713..88f8da8a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,20 +10,20 @@ jobs: with: fetch-depth: 0 show-progress: false - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: java-version: 17 distribution: 'temurin' cache: 'maven' - name: Cache SonarCloud packages - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.sonar/cache key: ${{ runner.os }}-sonar restore-keys: ${{ runner.os }}-sonar - name: Ensure to use tagged version if: startsWith(github.ref, 'refs/tags/') - run: mvn versions:set --file ./pom.xml -DnewVersion=${GITHUB_REF##*/} + run: mvn -B versions:set --file ./pom.xml -DnewVersion=${GITHUB_REF##*/} - name: Build and Test run: > mvn -B verify @@ -36,7 +36,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: artifacts path: target/*.jar diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index b90c55f8..237bcac3 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -20,16 +20,16 @@ jobs: with: fetch-depth: 2 show-progress: false - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: java-version: 17 distribution: 'temurin' cache: 'maven' - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: java - name: Build run: mvn -B install -DskipTests - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 \ No newline at end of file + uses: github/codeql-action/analyze@v3 \ No newline at end of file diff --git a/.github/workflows/dependency-check.yml b/.github/workflows/dependency-check.yml new file mode 100644 index 00000000..4e7e7d0f --- /dev/null +++ b/.github/workflows/dependency-check.yml @@ -0,0 +1,20 @@ +name: OWASP Maven Dependency Check +on: + schedule: + - cron: '0 10 * * 0' + push: + branches: + - 'release/**' + workflow_dispatch: + + +jobs: + check-dependencies: + uses: skymatic/workflows/.github/workflows/run-dependency-check.yml@v1 + with: + runner-os: 'ubuntu-latest' + java-distribution: 'temurin' + java-version: 17 + secrets: + nvd-api-key: ${{ secrets.NVD_API_KEY }} + slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }} diff --git a/.github/workflows/publish-central.yml b/.github/workflows/publish-central.yml index 3260070c..9eb1b363 100644 --- a/.github/workflows/publish-central.yml +++ b/.github/workflows/publish-central.yml @@ -14,7 +14,7 @@ jobs: with: ref: "refs/tags/${{ github.event.inputs.tag }}" show-progress: false - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: java-version: 17 distribution: 'temurin' diff --git a/.github/workflows/publish-github.yml b/.github/workflows/publish-github.yml index 37166beb..e0f8b793 100644 --- a/.github/workflows/publish-github.yml +++ b/.github/workflows/publish-github.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v4 with: show-progress: false - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: java-version: 17 distribution: 'temurin' diff --git a/pom.xml b/pom.xml index 1b93bbea..95107f48 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 org.cryptomator cryptofs - 2.6.8 + 2.6.9 Cryptomator Crypto Filesystem This library provides the Java filesystem provider used by Cryptomator. https://github.com/cryptomator/cryptofs @@ -20,19 +20,19 @@ 2.1.2 4.4.0 - 2.48.1 + 2.49 32.1.3-jre 3.1.8 - 2.0.9 + 2.0.12 - 5.10.1 + 5.10.2 5.2.0 2.2 1.3.0 - 9.0.1 + 9.0.9 1.2.1 0.8.11 1.6.13 @@ -143,7 +143,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.11.0 + 3.12.1 true @@ -158,7 +158,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.2.2 + 3.2.5 me.fabriciorby @@ -197,7 +197,7 @@ maven-javadoc-plugin - 3.6.2 + 3.6.3 attach-javadocs @@ -247,17 +247,19 @@ dependency-check-maven ${dependency-check.version} - 24 + 24 0 true true suppression.xml + ${env.NVD_API_KEY} check + validate diff --git a/src/main/java/org/cryptomator/cryptofs/ch/CleartextFileChannel.java b/src/main/java/org/cryptomator/cryptofs/ch/CleartextFileChannel.java index 97791365..4723e80b 100644 --- a/src/main/java/org/cryptomator/cryptofs/ch/CleartextFileChannel.java +++ b/src/main/java/org/cryptomator/cryptofs/ch/CleartextFileChannel.java @@ -1,5 +1,6 @@ package org.cryptomator.cryptofs.ch; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import org.cryptomator.cryptofs.CryptoFileSystemStats; import org.cryptomator.cryptofs.EffectiveOpenOptions; @@ -245,7 +246,8 @@ private void flush() throws IOException { * * @throws IOException */ - private void persistLastModified() throws IOException { + @VisibleForTesting + void persistLastModified() throws IOException { FileTime lastModifiedTime = isWritable() ? FileTime.from(lastModified.get()) : null; FileTime lastAccessTime = FileTime.from(Instant.now()); var p = currentFilePath.get(); @@ -322,6 +324,7 @@ long beginOfChunk(long cleartextPos) { protected void implCloseChannel() throws IOException { try { flush(); + ciphertextFileChannel.force(true); try { persistLastModified(); } catch (NoSuchFileException nsfe) { diff --git a/src/test/java/org/cryptomator/cryptofs/ch/CleartextFileChannelTest.java b/src/test/java/org/cryptomator/cryptofs/ch/CleartextFileChannelTest.java index 8b07565a..89213ddf 100644 --- a/src/test/java/org/cryptomator/cryptofs/ch/CleartextFileChannelTest.java +++ b/src/test/java/org/cryptomator/cryptofs/ch/CleartextFileChannelTest.java @@ -51,7 +51,9 @@ import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -240,6 +242,17 @@ public void testCloseTriggersCloseListener() throws IOException { verify(closeListener).closed(inTest); } + @Test + @DisplayName("On close, first flush channel, then persist lastModified") + public void testCloseFlushBeforePersist() throws IOException { + var inSpy = spy(inTest); + inSpy.implCloseChannel(); + + var ordering = inOrder(inSpy, ciphertextFileChannel); + ordering.verify(ciphertextFileChannel).force(true); + ordering.verify(inSpy).persistLastModified(); + } + @Test public void testCloseUpdatesLastModifiedTimeIfWriteable() throws IOException { when(options.writable()).thenReturn(true);