From 0ad91f6d4d550ac6c3fdcb38ec6fa4e9bb7d2030 Mon Sep 17 00:00:00 2001 From: Pranav-0440 Date: Tue, 10 Feb 2026 23:04:35 +0530 Subject: [PATCH 1/8] Fail fast at startup if local storage directory is not writable Signed-off-by: Pranav-0440 --- .../openvsx/storage/LocalStorageService.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/server/src/main/java/org/eclipse/openvsx/storage/LocalStorageService.java b/server/src/main/java/org/eclipse/openvsx/storage/LocalStorageService.java index 62c8860a0..808362c9f 100644 --- a/server/src/main/java/org/eclipse/openvsx/storage/LocalStorageService.java +++ b/server/src/main/java/org/eclipse/openvsx/storage/LocalStorageService.java @@ -8,6 +8,7 @@ * SPDX-License-Identifier: EPL-2.0 * ****************************************************************************** */ package org.eclipse.openvsx.storage; +import jakarta.annotation.PostConstruct; import org.apache.commons.lang3.StringUtils; import org.eclipse.openvsx.entities.FileResource; @@ -40,6 +41,32 @@ public class LocalStorageService implements IStorageService { public boolean isEnabled() { return !StringUtils.isEmpty(storageDirectory); } + + @PostConstruct + public void validateStorageDirectory() { + if (!isEnabled()) { + return; + } + + try { + Path dir = Path.of(storageDirectory).toAbsolutePath(); + + // Ensure directory exists + Files.createDirectories(dir); + + // Verify directory is writable by creating a temp file + Path testFile = dir.resolve(".ovsx_write_test"); + Files.writeString(testFile, "test"); + Files.deleteIfExists(testFile); + + } catch (Exception e) { + throw new IllegalStateException( + "Local storage directory is not writable: " + storageDirectory + + ". Please check permissions for 'ovsx.storage.local.directory'.", + e + ); + } + } @Override public void uploadFile(TempFile tempFile) { From 413e8479de805f37726bcfe55938ba0f5eed35c4 Mon Sep 17 00:00:00 2001 From: Pranav-0440 Date: Tue, 10 Feb 2026 23:34:30 +0530 Subject: [PATCH 2/8] Harden startup validation for local storage directory --- .vscode/settings.json | 3 ++- .../openvsx/storage/LocalStorageService.java | 15 +++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 251001f9d..463f3b874 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,5 +13,6 @@ "runServer" ] }, - "java.saveActions.organizeImports": true + "java.saveActions.organizeImports": true, + "java.compile.nullAnalysis.mode": "automatic" } \ No newline at end of file diff --git a/server/src/main/java/org/eclipse/openvsx/storage/LocalStorageService.java b/server/src/main/java/org/eclipse/openvsx/storage/LocalStorageService.java index 808362c9f..071b1df86 100644 --- a/server/src/main/java/org/eclipse/openvsx/storage/LocalStorageService.java +++ b/server/src/main/java/org/eclipse/openvsx/storage/LocalStorageService.java @@ -8,6 +8,7 @@ * SPDX-License-Identifier: EPL-2.0 * ****************************************************************************** */ package org.eclipse.openvsx.storage; + import jakarta.annotation.PostConstruct; import org.apache.commons.lang3.StringUtils; @@ -54,10 +55,16 @@ public void validateStorageDirectory() { // Ensure directory exists Files.createDirectories(dir); - // Verify directory is writable by creating a temp file - Path testFile = dir.resolve(".ovsx_write_test"); - Files.writeString(testFile, "test"); - Files.deleteIfExists(testFile); + // Verify directory is writable by creating and removing a temp file + Path testFile = null; + try { + testFile = Files.createTempFile(dir, ".ovsx_write_test", null); + Files.writeString(testFile, "test"); + } finally { + if (testFile != null) { + Files.deleteIfExists(testFile); + } + } } catch (Exception e) { throw new IllegalStateException( From 53b4f0683b2b01495559cd5784ad05af7fe249b2 Mon Sep 17 00:00:00 2001 From: Pranav-0440 Date: Wed, 11 Feb 2026 19:29:57 +0530 Subject: [PATCH 3/8] Use Files.isWritable to validate local storage permissions Signed-off-by: Pranav-0440 --- .../openvsx/storage/LocalStorageService.java | 43 ++++++++----------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/server/src/main/java/org/eclipse/openvsx/storage/LocalStorageService.java b/server/src/main/java/org/eclipse/openvsx/storage/LocalStorageService.java index 071b1df86..4addebf1d 100644 --- a/server/src/main/java/org/eclipse/openvsx/storage/LocalStorageService.java +++ b/server/src/main/java/org/eclipse/openvsx/storage/LocalStorageService.java @@ -9,7 +9,13 @@ * ****************************************************************************** */ package org.eclipse.openvsx.storage; -import jakarta.annotation.PostConstruct; +import java.io.IOException; +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.List; import org.apache.commons.lang3.StringUtils; import org.eclipse.openvsx.entities.FileResource; @@ -24,13 +30,7 @@ import org.springframework.web.server.ServerErrorException; import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; -import java.io.IOException; -import java.net.URI; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import java.util.ArrayList; -import java.util.List; +import jakarta.annotation.PostConstruct; @Component public class LocalStorageService implements IStorageService { @@ -48,27 +48,18 @@ public void validateStorageDirectory() { if (!isEnabled()) { return; } - + Path dir = Path.of(storageDirectory).toAbsolutePath(); try { - Path dir = Path.of(storageDirectory).toAbsolutePath(); - - // Ensure directory exists Files.createDirectories(dir); - - // Verify directory is writable by creating and removing a temp file - Path testFile = null; - try { - testFile = Files.createTempFile(dir, ".ovsx_write_test", null); - Files.writeString(testFile, "test"); - } finally { - if (testFile != null) { - Files.deleteIfExists(testFile); - } - } - - } catch (Exception e) { + if (!Files.isDirectory(dir) || !Files.isWritable(dir)) { + throw new IllegalStateException( + "Local storage directory is not writable: " + dir + + ". Please check permissions for 'ovsx.storage.local.directory'." + ); + } + } catch (IOException e) { throw new IllegalStateException( - "Local storage directory is not writable: " + storageDirectory + + "Failed to initialize local storage directory: " + dir + ". Please check permissions for 'ovsx.storage.local.directory'.", e ); From ffe8d9880168b8bb7a367561269ecfc0257d8113 Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Wed, 11 Feb 2026 15:19:08 +0100 Subject: [PATCH 4/8] Remove duplicate Java settings in VS Code --- .vscode/settings.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 463f3b874..eb25e6355 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,6 +13,5 @@ "runServer" ] }, - "java.saveActions.organizeImports": true, - "java.compile.nullAnalysis.mode": "automatic" -} \ No newline at end of file + "java.saveActions.organizeImports": true +} From d8e2f165f730c6dff798c5df98d899e04b587f6b Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Wed, 11 Feb 2026 15:19:30 +0100 Subject: [PATCH 5/8] Fix JSON formatting in settings.json From c6c4de1c3e371dcef5b354f688ba68b0fd068391 Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Wed, 11 Feb 2026 15:23:26 +0100 Subject: [PATCH 6/8] Update settings.json From 80790584d8f6edcd9e66883436e329e501441ffc Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Wed, 11 Feb 2026 15:24:24 +0100 Subject: [PATCH 7/8] Fix duplicate import in LocalStorageService Removed duplicate import of jakarta.annotation.PostConstruct. --- .../java/org/eclipse/openvsx/storage/LocalStorageService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/org/eclipse/openvsx/storage/LocalStorageService.java b/server/src/main/java/org/eclipse/openvsx/storage/LocalStorageService.java index 4addebf1d..01497dff5 100644 --- a/server/src/main/java/org/eclipse/openvsx/storage/LocalStorageService.java +++ b/server/src/main/java/org/eclipse/openvsx/storage/LocalStorageService.java @@ -17,6 +17,8 @@ import java.util.ArrayList; import java.util.List; +import jakarta.annotation.PostConstruct; + import org.apache.commons.lang3.StringUtils; import org.eclipse.openvsx.entities.FileResource; import org.eclipse.openvsx.entities.Namespace; @@ -30,8 +32,6 @@ import org.springframework.web.server.ServerErrorException; import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; -import jakarta.annotation.PostConstruct; - @Component public class LocalStorageService implements IStorageService { From 6cf3d398fe58533c7153c871013922c53a3a929d Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Wed, 11 Feb 2026 15:38:27 +0100 Subject: [PATCH 8/8] simplify logic --- .vscode/settings.json | 2 +- .../openvsx/storage/LocalStorageService.java | 30 +++++++++---------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index eb25e6355..251001f9d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -14,4 +14,4 @@ ] }, "java.saveActions.organizeImports": true -} +} \ No newline at end of file diff --git a/server/src/main/java/org/eclipse/openvsx/storage/LocalStorageService.java b/server/src/main/java/org/eclipse/openvsx/storage/LocalStorageService.java index 01497dff5..f9c81bc70 100644 --- a/server/src/main/java/org/eclipse/openvsx/storage/LocalStorageService.java +++ b/server/src/main/java/org/eclipse/openvsx/storage/LocalStorageService.java @@ -44,25 +44,23 @@ public boolean isEnabled() { } @PostConstruct - public void validateStorageDirectory() { + public void validateStorageDirectory() throws IOException { if (!isEnabled()) { return; } - Path dir = Path.of(storageDirectory).toAbsolutePath(); - try { - Files.createDirectories(dir); - if (!Files.isDirectory(dir) || !Files.isWritable(dir)) { - throw new IllegalStateException( - "Local storage directory is not writable: " + dir + - ". Please check permissions for 'ovsx.storage.local.directory'." - ); - } - } catch (IOException e) { - throw new IllegalStateException( - "Failed to initialize local storage directory: " + dir + - ". Please check permissions for 'ovsx.storage.local.directory'.", - e - ); + + var storageDirectoryPath = Path.of(storageDirectory).toAbsolutePath(); + + if (!Files.exists(storageDirectoryPath)) { + Files.createDirectories(storageDirectoryPath); + } + + if (!Files.isDirectory(storageDirectoryPath)) { + throw new IllegalStateException("Local storage directory '" + storageDirectory + "' is not a directory"); + } + + if (!Files.isWritable(storageDirectoryPath)) { + throw new IllegalStateException("Local storage directory '" + storageDirectory + "' is not writable"); } }