diff --git a/server/src/main/java/org/eclipse/openvsx/LocalRegistryService.java b/server/src/main/java/org/eclipse/openvsx/LocalRegistryService.java index 3a2b5ee5b..670da1571 100644 --- a/server/src/main/java/org/eclipse/openvsx/LocalRegistryService.java +++ b/server/src/main/java/org/eclipse/openvsx/LocalRegistryService.java @@ -38,6 +38,7 @@ import org.eclipse.openvsx.eclipse.EclipseService; import org.eclipse.openvsx.entities.*; import org.eclipse.openvsx.json.*; +import org.eclipse.openvsx.migration.MigrationsProperties; import org.eclipse.openvsx.publish.ExtensionVersionIntegrityService; import org.eclipse.openvsx.publish.PublishingConfig; import org.eclipse.openvsx.repositories.RepositoryService; @@ -62,6 +63,7 @@ import org.eclipse.openvsx.util.VersionService; import org.eclipse.openvsx.util.auth.AuthenticatedUser; import org.eclipse.openvsx.util.auth.LoggedInAuthentication; +import org.eclipse.openvsx.web.WebUiProperties; import static org.eclipse.openvsx.cache.CacheService.*; import static org.eclipse.openvsx.entities.FileResource.*; @@ -89,6 +91,8 @@ public class LocalRegistryService implements IExtensionRegistry { private final SimilarityCheckService similarityCheckService; private final PublishingConfig publishingConfig; private final TrustedPublishingConfig trustedPublishingConfig; + private final MigrationsProperties migrationsProperties; + private final WebUiProperties webUi; /** * How far behind the present the changes feed stops, see {@link #visibleUntil}. @@ -111,6 +115,8 @@ public LocalRegistryService( @Nullable SimilarityCheckService similarityCheckService, PublishingConfig publishingConfig, TrustedPublishingConfig trustedPublishingConfig, + MigrationsProperties migrationsProperties, + WebUiProperties webUi, @Value("${ovsx.changes-feed.lag:PT30S}") Duration changesFeedLag ) { this.entityManager = entityManager; @@ -128,15 +134,11 @@ public LocalRegistryService( this.similarityCheckService = similarityCheckService; this.publishingConfig = publishingConfig; this.trustedPublishingConfig = trustedPublishingConfig; + this.migrationsProperties = migrationsProperties; + this.webUi = webUi; this.changesFeedLag = changesFeedLag; } - @Value("${ovsx.webui.url:}") - String webuiUrl; - - @Value("${ovsx.registry.version:}") - String registryVersion; - @Override public NamespaceJson getNamespace(String namespaceName) { return getNamespace(namespaceName, false); @@ -1330,7 +1332,7 @@ private ExtensionReplacementJson toReplacementJson( return null; } - var baseUrl = webui ? webuiUrl : UrlUtil.getBaseUrl(); + var baseUrl = webui ? webUi.getUrl() : UrlUtil.getBaseUrl(); var segments = new String[] { webui ? "extension" : "api", replacement.getExtension().getNamespace().getName(), @@ -1377,6 +1379,7 @@ public String getPublicKey(String publicId) { @Override public RegistryVersionJson getRegistryVersion() { + var registryVersion = migrationsProperties.getRegistryVersion(); if (StringUtils.isEmpty(registryVersion)) { throw new NotFoundException(); } diff --git a/server/src/main/java/org/eclipse/openvsx/RestTemplateConfig.java b/server/src/main/java/org/eclipse/openvsx/RestTemplateConfig.java index 577e186b2..d15afc689 100644 --- a/server/src/main/java/org/eclipse/openvsx/RestTemplateConfig.java +++ b/server/src/main/java/org/eclipse/openvsx/RestTemplateConfig.java @@ -26,6 +26,8 @@ import org.springframework.web.client.RestTemplate; import org.springframework.web.util.DefaultUriBuilderFactory; +import org.eclipse.openvsx.mirror.MirrorConfig; + @Configuration public class RestTemplateConfig { @@ -154,11 +156,11 @@ public RestTemplate backgroundNonRedirectingRestTemplate( @Bean public RestTemplate vsCodeIdRestTemplate( - @Value("${ovsx.data.mirror.enabled:false}") boolean mirrorModeEnabled, + MirrorConfig mirrorConfig, RestTemplate restTemplate, RestTemplate backgroundRestTemplate ) { - return mirrorModeEnabled ? backgroundRestTemplate : restTemplate; + return mirrorConfig.isEnabled() ? backgroundRestTemplate : restTemplate; } private HttpClientBuilder createHttpClientBuilder(HttpConnPoolConfig httpConnPoolConfig) { diff --git a/server/src/main/java/org/eclipse/openvsx/accesstoken/AccessTokenConfig.java b/server/src/main/java/org/eclipse/openvsx/accesstoken/AccessTokenConfig.java index 6a18940a1..6a61d6774 100644 --- a/server/src/main/java/org/eclipse/openvsx/accesstoken/AccessTokenConfig.java +++ b/server/src/main/java/org/eclipse/openvsx/accesstoken/AccessTokenConfig.java @@ -22,8 +22,17 @@ import org.springframework.context.annotation.Configuration; import org.springframework.util.StringUtils; +import org.eclipse.openvsx.mirror.MirrorConfig; + @Configuration public class AccessTokenConfig { + + private final MirrorConfig mirrorConfig; + + public AccessTokenConfig(MirrorConfig mirrorConfig) { + this.mirrorConfig = mirrorConfig; + } + /** * The token prefix to use when generating a new access token. *

@@ -116,9 +125,6 @@ public class AccessTokenConfig { @Value("${ovsx.access-token.token-hash-salt:}") private String tokenHashSalt; - @Value("${ovsx.data.mirror.enabled:false}") - private boolean mirrorEnabled; - public @NonNull String getPrefix() { return this.prefix; } @@ -173,7 +179,7 @@ public boolean hasNotificationSchedule() { @PostConstruct public void validate() { - if (isTokenExpiryEnabled() && mirrorEnabled) { + if (isTokenExpiryEnabled() && mirrorConfig.isEnabled()) { throw new IllegalArgumentException( "ovsx.access-token.expiration can not be enabled when mirror mode is active, got: " + expiration); } diff --git a/server/src/main/java/org/eclipse/openvsx/adapter/LocalVSCodeService.java b/server/src/main/java/org/eclipse/openvsx/adapter/LocalVSCodeService.java index 487010a52..7da37a8a4 100644 --- a/server/src/main/java/org/eclipse/openvsx/adapter/LocalVSCodeService.java +++ b/server/src/main/java/org/eclipse/openvsx/adapter/LocalVSCodeService.java @@ -48,6 +48,7 @@ import org.eclipse.openvsx.util.TimeUtil; import org.eclipse.openvsx.util.UrlUtil; import org.eclipse.openvsx.util.VersionService; +import org.eclipse.openvsx.web.WebUiProperties; import static org.eclipse.openvsx.adapter.ExtensionQueryParam.*; import static org.eclipse.openvsx.adapter.ExtensionQueryParam.Criterion.*; @@ -68,6 +69,7 @@ public class LocalVSCodeService implements IVSCodeService { private final ExtensionVersionIntegrityService integrityService; private final WebResourceService webResources; private final CacheService cache; + private final WebUiProperties webUi; private final Map assets = Map.of( FILE_VSIX, @@ -87,9 +89,6 @@ public class LocalVSCodeService implements IVSCodeService { FILE_SIGNATURE, DOWNLOAD_SIG); - @Value("${ovsx.webui.url:}") - String webuiUrl; - // See RepositoryService.findActiveExtensionVersions / ExtensionVersionJooqRepository - // caps how many of an extension's active pre-release versions the version listing below // fetches per extensionQuery request; regular releases are never capped. A negative value @@ -105,7 +104,8 @@ public LocalVSCodeService( StorageUtilService storageUtil, ExtensionVersionIntegrityService integrityService, WebResourceService webResources, - CacheService cache + CacheService cache, + WebUiProperties webUi ) { this.repositories = repositories; this.versions = versions; @@ -114,6 +114,7 @@ public LocalVSCodeService( this.integrityService = integrityService; this.webResources = webResources; this.cache = cache; + this.webUi = webUi; } @Override @@ -466,7 +467,11 @@ public String getItemUrl(String namespaceName, String extensionName) { throw new NotFoundException(); } - return UrlUtil.createApiUrl(webuiUrl, "extension", extension.getNamespace().getName(), extension.getName()); + return UrlUtil.createApiUrl( + webUi.getUrl(), + "extension", + extension.getNamespace().getName(), + extension.getName()); } @Override diff --git a/server/src/main/java/org/eclipse/openvsx/adapter/VSCodeIdService.java b/server/src/main/java/org/eclipse/openvsx/adapter/VSCodeIdService.java index 7268a3a55..c6449c90d 100644 --- a/server/src/main/java/org/eclipse/openvsx/adapter/VSCodeIdService.java +++ b/server/src/main/java/org/eclipse/openvsx/adapter/VSCodeIdService.java @@ -27,6 +27,8 @@ import org.eclipse.openvsx.UrlConfigService; import org.eclipse.openvsx.entities.Extension; import org.eclipse.openvsx.migration.HandlerJobRequest; +import org.eclipse.openvsx.migration.MigrationsProperties; +import org.eclipse.openvsx.mirror.MirrorConfig; import org.eclipse.openvsx.util.NamingUtil; import org.eclipse.openvsx.util.TimeUtil; import org.eclipse.openvsx.util.UUIDService; @@ -39,36 +41,36 @@ public class VSCodeIdService { private final UrlConfigService urlConfigService; private final JobRequestScheduler scheduler; private final UUIDService uuidService; - - @Value("${ovsx.data.mirror.enabled:false}") - boolean mirrorEnabled; + private final MirrorConfig mirrorConfig; + private final MigrationsProperties migrationsProperties; @Value("${ovsx.vscode.upstream.update-on-start:false}") boolean updateOnStart; - @Value("${ovsx.migrations.delay.seconds:0}") - long delay; - public VSCodeIdService( RestTemplate vsCodeIdRestTemplate, UrlConfigService urlConfigService, JobRequestScheduler scheduler, - UUIDService uuidService + UUIDService uuidService, + MirrorConfig mirrorConfig, + MigrationsProperties migrationsProperties ) { this.vsCodeIdRestTemplate = vsCodeIdRestTemplate; this.urlConfigService = urlConfigService; this.scheduler = scheduler; this.uuidService = uuidService; + this.mirrorConfig = mirrorConfig; + this.migrationsProperties = migrationsProperties; } @EventListener public void applicationStarted(ApplicationStartedEvent event) { - if (mirrorEnabled) { + if (mirrorConfig.isEnabled()) { return; } if (updateOnStart) { scheduler.schedule( - TimeUtil.getCurrentUTC().plusSeconds(delay), + TimeUtil.getCurrentUTC().plusSeconds(migrationsProperties.getDelaySeconds()), new HandlerJobRequest<>(VSCodeIdDailyUpdateJobRequestHandler.class)); } diff --git a/server/src/main/java/org/eclipse/openvsx/extension_control/ExtensionControlService.java b/server/src/main/java/org/eclipse/openvsx/extension_control/ExtensionControlService.java index 8e8449203..ea2d911f4 100644 --- a/server/src/main/java/org/eclipse/openvsx/extension_control/ExtensionControlService.java +++ b/server/src/main/java/org/eclipse/openvsx/extension_control/ExtensionControlService.java @@ -34,6 +34,8 @@ import org.eclipse.openvsx.cache.CacheService; import org.eclipse.openvsx.entities.UserData; import org.eclipse.openvsx.migration.HandlerJobRequest; +import org.eclipse.openvsx.migration.MigrationsProperties; +import org.eclipse.openvsx.mirror.MirrorConfig; import org.eclipse.openvsx.repositories.RepositoryService; import org.eclipse.openvsx.search.SearchUtilService; import org.eclipse.openvsx.util.ExtensionId; @@ -52,9 +54,8 @@ public class ExtensionControlService { private final EntityManager entityManager; private final SearchUtilService search; private final CacheService cache; - - @Value("${ovsx.data.mirror.enabled:false}") - boolean mirrorEnabled; + private final MirrorConfig mirrorConfig; + private final MigrationsProperties migrationsProperties; @Value("${ovsx.extension-control.enabled:true}") boolean enabled; @@ -65,31 +66,32 @@ public class ExtensionControlService { @Value("${ovsx.extension-control.update-on-start:false}") boolean updateOnStart; - @Value("${ovsx.migrations.delay.seconds:0}") - long delay; - public ExtensionControlService( JobRequestScheduler scheduler, RepositoryService repositories, EntityManager entityManager, SearchUtilService search, - CacheService cache + CacheService cache, + MirrorConfig mirrorConfig, + MigrationsProperties migrationsProperties ) { this.scheduler = scheduler; this.repositories = repositories; this.entityManager = entityManager; this.search = search; this.cache = cache; + this.mirrorConfig = mirrorConfig; + this.migrationsProperties = migrationsProperties; } @EventListener public void applicationStarted(ApplicationStartedEvent event) { - if (!enabled || mirrorEnabled) { + if (!enabled || mirrorConfig.isEnabled()) { scheduler.deleteRecurringJob("UpdateExtensionControl"); } else { if (updateOnStart) { scheduler.schedule( - TimeUtil.getCurrentUTC().plusSeconds(delay), + TimeUtil.getCurrentUTC().plusSeconds(migrationsProperties.getDelaySeconds()), new HandlerJobRequest<>(ExtensionControlJobRequestHandler.class)); } diff --git a/server/src/main/java/org/eclipse/openvsx/migration/GenerateKeyPairJobRequestHandler.java b/server/src/main/java/org/eclipse/openvsx/migration/GenerateKeyPairJobRequestHandler.java index df6b00226..5a0d41592 100644 --- a/server/src/main/java/org/eclipse/openvsx/migration/GenerateKeyPairJobRequestHandler.java +++ b/server/src/main/java/org/eclipse/openvsx/migration/GenerateKeyPairJobRequestHandler.java @@ -17,7 +17,6 @@ import org.jobrunr.scheduling.JobRequestScheduler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.dao.DataAccessException; import org.springframework.stereotype.Component; @@ -25,6 +24,7 @@ import org.eclipse.openvsx.admin.RemoveFileJobRequest; import org.eclipse.openvsx.entities.ExtensionVersion; import org.eclipse.openvsx.entities.FileResource; +import org.eclipse.openvsx.publish.ExtensionVersionIntegrityService; import org.eclipse.openvsx.repositories.RepositoryService; import static org.eclipse.openvsx.entities.FileResource.DOWNLOAD_SIG; @@ -39,23 +39,24 @@ public class GenerateKeyPairJobRequestHandler implements JobRequestHandler jobRequest) throws Exception { + var keyPairMode = integrityService.getKeyPairMode(); logger.info("Starting signature key-pair generation in mode {}", keyPairMode); switch (keyPairMode) { diff --git a/server/src/main/java/org/eclipse/openvsx/migration/MigrationScheduler.java b/server/src/main/java/org/eclipse/openvsx/migration/MigrationScheduler.java index 7e249b094..a86cc792a 100644 --- a/server/src/main/java/org/eclipse/openvsx/migration/MigrationScheduler.java +++ b/server/src/main/java/org/eclipse/openvsx/migration/MigrationScheduler.java @@ -17,6 +17,8 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; +import org.eclipse.openvsx.mirror.MirrorConfig; + @Component public class MigrationScheduler implements JobRequestHandler> { @@ -26,9 +28,7 @@ public class MigrationScheduler implements JobRequestHandler jobRequest) throws Exception { orphanNamespaceMigration.fixOrphanNamespaces(); - if (!mirrorEnabled) { + if (!mirrorConfig.isEnabled()) { scheduler.enqueue(new HandlerJobRequest<>(GenerateKeyPairJobRequestHandler.class)); } diff --git a/server/src/main/java/org/eclipse/openvsx/migration/MigrationsProperties.java b/server/src/main/java/org/eclipse/openvsx/migration/MigrationsProperties.java new file mode 100644 index 000000000..8acb2b6a2 --- /dev/null +++ b/server/src/main/java/org/eclipse/openvsx/migration/MigrationsProperties.java @@ -0,0 +1,39 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + ********************************************************************************/ +package org.eclipse.openvsx.migration; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +/** + * {@code ovsx.migrations.delay.seconds} and {@code ovsx.registry.version}, previously declared + * independently in every startup job that delays itself behind the registry's own start-up + * (migrations, VS Code id daily update, extension control update). + */ +@Component +public class MigrationsProperties { + + @Value("${ovsx.migrations.delay.seconds:0}") + private long delaySeconds; + + @Value("${ovsx.registry.version:}") + private String registryVersion; + + public long getDelaySeconds() { + return delaySeconds; + } + + public String getRegistryVersion() { + return registryVersion; + } +} diff --git a/server/src/main/java/org/eclipse/openvsx/migration/ScheduleMigrationsListener.java b/server/src/main/java/org/eclipse/openvsx/migration/ScheduleMigrationsListener.java index 26147267d..a71254c85 100644 --- a/server/src/main/java/org/eclipse/openvsx/migration/ScheduleMigrationsListener.java +++ b/server/src/main/java/org/eclipse/openvsx/migration/ScheduleMigrationsListener.java @@ -26,32 +26,32 @@ public class ScheduleMigrationsListener { protected final Logger logger = LoggerFactory.getLogger(ScheduleMigrationsListener.class); - @Value("${ovsx.migrations.delay.seconds:0}") - long delay; - @Value("${ovsx.migrations.once-per-version:false}") boolean runMigrationsOncePerVersion; - @Value("${ovsx.registry.version:}") - String registryVersion; - private final JobRequestScheduler scheduler; private final UUIDService uuidService; + private final MigrationsProperties migrationsProperties; - public ScheduleMigrationsListener(JobRequestScheduler scheduler, UUIDService uuidService) { + public ScheduleMigrationsListener( + JobRequestScheduler scheduler, + UUIDService uuidService, + MigrationsProperties migrationsProperties + ) { this.scheduler = scheduler; this.uuidService = uuidService; + this.migrationsProperties = migrationsProperties; } @EventListener public void applicationStarted(ApplicationStartedEvent event) { UUID jobId = null; if (runMigrationsOncePerVersion) { - var jobIdText = "MigrationScheduler::" + registryVersion; + var jobIdText = "MigrationScheduler::" + migrationsProperties.getRegistryVersion(); jobId = uuidService.generateFromName(jobIdText); } - var instant = Instant.now().plusSeconds(delay); + var instant = Instant.now().plusSeconds(migrationsProperties.getDelaySeconds()); scheduler.schedule(jobId, instant, new HandlerJobRequest<>(MigrationScheduler.class)); } } diff --git a/server/src/main/java/org/eclipse/openvsx/mirror/MirrorConfig.java b/server/src/main/java/org/eclipse/openvsx/mirror/MirrorConfig.java index 22b77161d..fdfbb7da6 100644 --- a/server/src/main/java/org/eclipse/openvsx/mirror/MirrorConfig.java +++ b/server/src/main/java/org/eclipse/openvsx/mirror/MirrorConfig.java @@ -12,6 +12,7 @@ import java.util.HashSet; import java.util.Set; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -19,6 +20,13 @@ @Configuration public class MirrorConfig { + @Value("${ovsx.data.mirror.enabled:false}") + private boolean enabled; + + public boolean isEnabled() { + return enabled; + } + @Bean @ConfigurationProperties(prefix = "ovsx.data.mirror.exclude-extensions") public Set excludeExtensions() { diff --git a/server/src/main/java/org/eclipse/openvsx/publish/ExtensionVersionIntegrityService.java b/server/src/main/java/org/eclipse/openvsx/publish/ExtensionVersionIntegrityService.java index 3d0c3fea8..5d91b77e5 100644 --- a/server/src/main/java/org/eclipse/openvsx/publish/ExtensionVersionIntegrityService.java +++ b/server/src/main/java/org/eclipse/openvsx/publish/ExtensionVersionIntegrityService.java @@ -65,6 +65,10 @@ public boolean isEnabled() { return keyPairMode.equals(KEYPAIR_MODE_CREATE) || keyPairMode.equals(KEYPAIR_MODE_RENEW); } + public String getKeyPairMode() { + return keyPairMode; + } + public boolean verifyExtensionVersion(TempFile extensionFile, TempFile signatureFile, TempFile publicKeyFile) { AsymmetricKeyParameter publicKeyParameters; try (var inReader = new InputStreamReader(Files.newInputStream(publicKeyFile.getPath()))) { diff --git a/server/src/main/java/org/eclipse/openvsx/security/SecurityConfig.java b/server/src/main/java/org/eclipse/openvsx/security/SecurityConfig.java index 34aab3b11..cded40a82 100644 --- a/server/src/main/java/org/eclipse/openvsx/security/SecurityConfig.java +++ b/server/src/main/java/org/eclipse/openvsx/security/SecurityConfig.java @@ -20,21 +20,21 @@ import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; +import org.eclipse.openvsx.web.WebUiProperties; + @Configuration @EnableWebSecurity public class SecurityConfig { - @Value("${ovsx.webui.url:}") - String webuiUrl; - - @Value( - "${ovsx.webui.frontendRoutes:/extension/**,/namespace/**,/search,/user-settings/**,/publish,/admin-dashboard/**}" - ) - String[] frontendRoutes; + private final WebUiProperties webUi; @Value("${ovsx.webui.additional-routes:}") String[] additionalRoutes; + public SecurityConfig(WebUiProperties webUi) { + this.webUi = webUi; + } + @Bean public SecurityFilterChain filterChain(HttpSecurity http, OAuth2UserServices userServices) throws Exception { var filterChain = http.authorizeHttpRequests( @@ -74,7 +74,7 @@ public SecurityFilterChain filterChain(HttpSecurity http, OAuth2UserServices use .permitAll() .requestMatchers(pathMatchers("/admin/**")) .hasAuthority("ROLE_ADMIN") - .requestMatchers(pathMatchers(frontendRoutes)) + .requestMatchers(pathMatchers(webUi.getFrontendRoutes())) .permitAll() .requestMatchers(pathMatchers(additionalRoutes)) .permitAll() @@ -95,6 +95,7 @@ public SecurityFilterChain filterChain(HttpSecurity http, OAuth2UserServices use .exceptionHandling(configurer -> configurer.authenticationEntryPoint(new Http403ForbiddenEntryPoint())); if (userServices.canLogin()) { + var webuiUrl = webUi.getUrl(); var redirectUrl = StringUtils.isEmpty(webuiUrl) ? "/" : webuiUrl; filterChain.oauth2Login(configurer -> { configurer.defaultSuccessUrl(redirectUrl); diff --git a/server/src/main/java/org/eclipse/openvsx/storage/AzureBlobStorageService.java b/server/src/main/java/org/eclipse/openvsx/storage/AzureBlobStorageService.java index 3479ccd95..a7e370427 100644 --- a/server/src/main/java/org/eclipse/openvsx/storage/AzureBlobStorageService.java +++ b/server/src/main/java/org/eclipse/openvsx/storage/AzureBlobStorageService.java @@ -70,6 +70,14 @@ public boolean isEnabled() { return !StringUtils.isEmpty(serviceEndpoint); } + public String getServiceEndpoint() { + return serviceEndpoint; + } + + public String getBlobContainer() { + return blobContainer; + } + protected BlobContainerClient getContainerClient() { if (containerClient == null) { containerClient = new BlobContainerClientBuilder() diff --git a/server/src/main/java/org/eclipse/openvsx/storage/log/AzureDownloadCountHandler.java b/server/src/main/java/org/eclipse/openvsx/storage/log/AzureDownloadCountHandler.java index bc6e989d6..66760ef6f 100644 --- a/server/src/main/java/org/eclipse/openvsx/storage/log/AzureDownloadCountHandler.java +++ b/server/src/main/java/org/eclipse/openvsx/storage/log/AzureDownloadCountHandler.java @@ -45,6 +45,7 @@ import org.eclipse.openvsx.entities.FileResource; import org.eclipse.openvsx.migration.HandlerJobRequest; import org.eclipse.openvsx.settings.SettingsService; +import org.eclipse.openvsx.storage.AzureBlobStorageService; import org.eclipse.openvsx.util.TempFile; import static org.eclipse.openvsx.storage.AzureBlobStorageService.AZURE_USER_AGENT; @@ -61,6 +62,7 @@ public class AzureDownloadCountHandler implements JobRequestHandler processBlobItem(String blobName) throws IOException if (isGetBlobOperation(node) && isStatusOk(node) && isExtensionPackageUri(node) && isNotOpenVSXUserAgent(node)) { var uri = node.get("uri").asString(); - pathParams = uri.substring(storageServiceEndpoint.length()).split("/"); + pathParams = uri.substring(storageService.getServiceEndpoint().length()).split("/"); } - if (pathParams != null && storageBlobContainer.equals(pathParams[1])) { + if (pathParams != null && storageService.getBlobContainer().equals(pathParams[1])) { var fileName = UriUtils.decode(pathParams[pathParams.length - 1], StandardCharsets.UTF_8) .toUpperCase(); fileCounts.merge(fileName, 1, Integer::sum); @@ -305,7 +306,7 @@ private boolean isCorrectName(String name) { private Pattern getBlobItemNamePattern() { if (blobItemNamePattern == null) { - var host = URI.create(storageServiceEndpoint).getHost(); + var host = URI.create(storageService.getServiceEndpoint()).getHost(); var storageAccount = host.substring(0, host.indexOf('.')); var regex = "^resourceId=/subscriptions/.*/resourceGroups/.*/providers/Microsoft\\.Storage/storageAccounts/" diff --git a/server/src/main/java/org/eclipse/openvsx/web/ServerErrorController.java b/server/src/main/java/org/eclipse/openvsx/web/ServerErrorController.java index b11550292..301575e26 100644 --- a/server/src/main/java/org/eclipse/openvsx/web/ServerErrorController.java +++ b/server/src/main/java/org/eclipse/openvsx/web/ServerErrorController.java @@ -11,7 +11,6 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.web.WebProperties; import org.springframework.boot.webmvc.autoconfigure.error.BasicErrorController; @@ -28,11 +27,11 @@ @ConditionalOnProperty(value = "spring.web.error.path", havingValue = "/server-error") public class ServerErrorController extends BasicErrorController { - @Value("${ovsx.webui.url:}") - String webuiUrl; + private final WebUiProperties webUi; - public ServerErrorController(ErrorAttributes errorAttributes, WebProperties webProperties) { + public ServerErrorController(ErrorAttributes errorAttributes, WebProperties webProperties, WebUiProperties webUi) { super(errorAttributes, webProperties.getError()); + this.webUi = webUi; } // Override errorHtml() itself rather than adding a new method with its own explicit @@ -43,6 +42,6 @@ public ServerErrorController(ErrorAttributes errorAttributes, WebProperties webP // the correct, property-driven path with no combination/doubling. @Override public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) { - return new ModelAndView("redirect:" + UrlUtil.createApiUrl(webuiUrl, "error")); + return new ModelAndView("redirect:" + UrlUtil.createApiUrl(webUi.getUrl(), "error")); } } diff --git a/server/src/main/java/org/eclipse/openvsx/web/SitemapService.java b/server/src/main/java/org/eclipse/openvsx/web/SitemapService.java index 65fcc54a1..2a9f8787b 100644 --- a/server/src/main/java/org/eclipse/openvsx/web/SitemapService.java +++ b/server/src/main/java/org/eclipse/openvsx/web/SitemapService.java @@ -22,7 +22,6 @@ import javax.xml.transform.stream.StreamResult; import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Component; @@ -35,12 +34,11 @@ public class SitemapService { private final RepositoryService repositories; + private final WebUiProperties webUi; - @Value("${ovsx.webui.url:}") - String webuiUrl; - - public SitemapService(RepositoryService repositories) { + public SitemapService(RepositoryService repositories, WebUiProperties webUi) { this.repositories = repositories; + this.webUi = webUi; } @Cacheable(CACHE_SITEMAP) @@ -78,6 +76,7 @@ public String generateSitemap() throws ParserConfigurationException, IOException } private String getBaseUrl() { + var webuiUrl = webUi.getUrl(); String url; if (StringUtils.isEmpty(webuiUrl)) { url = UrlUtil.getBaseUrl(); diff --git a/server/src/main/java/org/eclipse/openvsx/web/WebConfig.java b/server/src/main/java/org/eclipse/openvsx/web/WebConfig.java index e405bb39b..2523fc578 100644 --- a/server/src/main/java/org/eclipse/openvsx/web/WebConfig.java +++ b/server/src/main/java/org/eclipse/openvsx/web/WebConfig.java @@ -13,7 +13,6 @@ import java.util.Optional; import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; @@ -25,22 +24,21 @@ @Configuration public class WebConfig implements WebMvcConfigurer { - private MirrorExtensionHandlerInterceptor mirrorInterceptor; - - @Value("${ovsx.webui.url:}") - String webuiUrl; + private final WebUiProperties webUi; - @Value( - "${ovsx.webui.frontendRoutes:/extension/**,/namespace/**,/search,/user-settings/**,/publish,/admin-dashboard/**}" - ) - String[] frontendRoutes; + private MirrorExtensionHandlerInterceptor mirrorInterceptor; - public WebConfig(Optional mirrorExtensionHandlerInterceptor) { + public WebConfig( + WebUiProperties webUi, + Optional mirrorExtensionHandlerInterceptor + ) { + this.webUi = webUi; mirrorExtensionHandlerInterceptor.ifPresent(service -> this.mirrorInterceptor = service); } @Override public void addCorsMappings(CorsRegistry registry) { + var webuiUrl = webUi.getUrl(); if (!StringUtils.isEmpty(webuiUrl) && URI.create(webuiUrl).isAbsolute()) { // The Web UI is given with an absolute URL, so we need to enable CORS with credentials. var authorizedEndpoints = new String[] { @@ -71,7 +69,7 @@ public void addCorsMappings(CorsRegistry registry) { @Override public void addViewControllers(ViewControllerRegistry registry) { - for (var route : frontendRoutes) { + for (var route : webUi.getFrontendRoutes()) { registry.addViewController(route).setViewName("forward:/index.html"); } } diff --git a/server/src/main/java/org/eclipse/openvsx/web/WebUiProperties.java b/server/src/main/java/org/eclipse/openvsx/web/WebUiProperties.java new file mode 100644 index 000000000..bac19d0ec --- /dev/null +++ b/server/src/main/java/org/eclipse/openvsx/web/WebUiProperties.java @@ -0,0 +1,40 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + ********************************************************************************/ +package org.eclipse.openvsx.web; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +/** + * The web UI's own URL and the frontend routes it serves, previously declared independently + * (and identically) in both {@link WebConfig} and {@code SecurityConfig}. + */ +@Component +public class WebUiProperties { + + @Value("${ovsx.webui.url:}") + private String url; + + @Value( + "${ovsx.webui.frontendRoutes:/extension/**,/namespace/**,/search,/user-settings/**,/publish,/admin-dashboard/**}" + ) + private String[] frontendRoutes; + + public String getUrl() { + return url; + } + + public String[] getFrontendRoutes() { + return frontendRoutes; + } +} diff --git a/server/src/test/java/org/eclipse/openvsx/LocalRegistryServiceTest.java b/server/src/test/java/org/eclipse/openvsx/LocalRegistryServiceTest.java index 6044c5835..76b06555f 100644 --- a/server/src/test/java/org/eclipse/openvsx/LocalRegistryServiceTest.java +++ b/server/src/test/java/org/eclipse/openvsx/LocalRegistryServiceTest.java @@ -44,6 +44,7 @@ import org.eclipse.openvsx.entities.PersonalAccessTokenType; import org.eclipse.openvsx.entities.UserData; import org.eclipse.openvsx.json.NamespaceJson; +import org.eclipse.openvsx.migration.MigrationsProperties; import org.eclipse.openvsx.publish.ExtensionVersionIntegrityService; import org.eclipse.openvsx.publish.PublishingConfig; import org.eclipse.openvsx.repositories.RepositoryService; @@ -55,6 +56,7 @@ import org.eclipse.openvsx.util.TempFile; import org.eclipse.openvsx.util.VersionService; import org.eclipse.openvsx.util.auth.AccessTokenAuthentication; +import org.eclipse.openvsx.web.WebUiProperties; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -129,6 +131,8 @@ void setUp() { similarityCheckService, new PublishingConfig(), new TrustedPublishingConfig(), + new MigrationsProperties(), + new WebUiProperties(), Duration.ofSeconds(30)); // A permissive default for a void method rather than a per-test expectation: the tests of diff --git a/server/src/test/java/org/eclipse/openvsx/RegistryAPITest.java b/server/src/test/java/org/eclipse/openvsx/RegistryAPITest.java index e4f68bea6..4e42ff913 100644 --- a/server/src/test/java/org/eclipse/openvsx/RegistryAPITest.java +++ b/server/src/test/java/org/eclipse/openvsx/RegistryAPITest.java @@ -66,6 +66,8 @@ import org.eclipse.openvsx.json.*; import org.eclipse.openvsx.mail.MailService; import org.eclipse.openvsx.metrics.ExtensionDownloadMetrics; +import org.eclipse.openvsx.migration.MigrationsProperties; +import org.eclipse.openvsx.mirror.MirrorConfig; import org.eclipse.openvsx.publish.ExtensionVersionIntegrityService; import org.eclipse.openvsx.publish.PublishExtensionVersionHandler; import org.eclipse.openvsx.publish.PublishExtensionVersionService; @@ -90,6 +92,7 @@ import org.eclipse.openvsx.util.UUIDService; import org.eclipse.openvsx.util.VersionAlias; import org.eclipse.openvsx.util.VersionService; +import org.eclipse.openvsx.web.WebUiProperties; import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.openvsx.entities.FileResource.*; @@ -3639,7 +3642,7 @@ private byte[] createExtensionPackageWithCollidingReadme(String name, String ver } @TestConfiguration - @Import({ SecurityConfig.class, MockMvcAsyncConfig.class }) + @Import({ SecurityConfig.class, MockMvcAsyncConfig.class, WebUiProperties.class }) static class TestConfig { @Bean TransactionTemplate transactionTemplate() { @@ -3673,7 +3676,7 @@ UUIDService uuidService() { @Bean AccessTokenConfig tokenConfig() { - return new AccessTokenConfig(); + return new AccessTokenConfig(new MirrorConfig()); } @Bean @@ -3741,6 +3744,8 @@ LocalRegistryService localRegistryService( similarityCheckService, publishingConfig, trustedPublishingConfig, + new MigrationsProperties(), + new WebUiProperties(), CHANGES_FEED_LAG); } diff --git a/server/src/test/java/org/eclipse/openvsx/UserAPITest.java b/server/src/test/java/org/eclipse/openvsx/UserAPITest.java index 185700a26..735285b3e 100644 --- a/server/src/test/java/org/eclipse/openvsx/UserAPITest.java +++ b/server/src/test/java/org/eclipse/openvsx/UserAPITest.java @@ -49,6 +49,8 @@ import org.eclipse.openvsx.entities.*; import org.eclipse.openvsx.json.*; import org.eclipse.openvsx.mail.MailService; +import org.eclipse.openvsx.migration.MigrationsProperties; +import org.eclipse.openvsx.mirror.MirrorConfig; import org.eclipse.openvsx.publish.ExtensionVersionIntegrityService; import org.eclipse.openvsx.publish.PublishExtensionVersionHandler; import org.eclipse.openvsx.publish.PublishingConfig; @@ -70,6 +72,7 @@ import org.eclipse.openvsx.util.TargetPlatformVersion; import org.eclipse.openvsx.util.UUIDService; import org.eclipse.openvsx.util.VersionService; +import org.eclipse.openvsx.web.WebUiProperties; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -1154,7 +1157,7 @@ public Boolean answer(InvocationOnMock invocation) { } @TestConfiguration - @Import(SecurityConfig.class) + @Import({ SecurityConfig.class, WebUiProperties.class }) static class TestConfig { @Bean TransactionTemplate transactionTemplate() { @@ -1188,7 +1191,7 @@ UUIDService uuidService() { @Bean AccessTokenConfig tokenConfig() { - return new AccessTokenConfig(); + return new AccessTokenConfig(new MirrorConfig()); } @Bean @@ -1259,6 +1262,8 @@ LocalRegistryService localRegistryService( similarityCheckService, new PublishingConfig(), new TrustedPublishingConfig(), + new MigrationsProperties(), + new WebUiProperties(), Duration.ofSeconds(30)); } diff --git a/server/src/test/java/org/eclipse/openvsx/adapter/LocalVSCodeServiceTest.java b/server/src/test/java/org/eclipse/openvsx/adapter/LocalVSCodeServiceTest.java index 8ffe03717..83ad940d5 100644 --- a/server/src/test/java/org/eclipse/openvsx/adapter/LocalVSCodeServiceTest.java +++ b/server/src/test/java/org/eclipse/openvsx/adapter/LocalVSCodeServiceTest.java @@ -20,6 +20,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -33,6 +34,7 @@ import org.eclipse.openvsx.search.SearchUtilService; import org.eclipse.openvsx.storage.*; import org.eclipse.openvsx.util.VersionService; +import org.eclipse.openvsx.web.WebUiProperties; import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.openvsx.adapter.ExtensionQueryParam.*; @@ -126,6 +128,7 @@ private ExtensionVersion mockExtensionVersion(Extension extension, long id, Stri } @TestConfiguration + @Import(WebUiProperties.class) static class TestConfig { @Bean LocalVSCodeService vsCodeService( @@ -135,7 +138,8 @@ LocalVSCodeService vsCodeService( StorageUtilService storageUtil, ExtensionVersionIntegrityService integrityService, WebResourceService webResources, - CacheService cache + CacheService cache, + WebUiProperties webUi ) { return new LocalVSCodeService( repositories, @@ -144,7 +148,8 @@ LocalVSCodeService vsCodeService( storageUtil, integrityService, webResources, - cache); + cache, + webUi); } } diff --git a/server/src/test/java/org/eclipse/openvsx/adapter/VSCodeAPITest.java b/server/src/test/java/org/eclipse/openvsx/adapter/VSCodeAPITest.java index 448644a7a..1afdd20b2 100644 --- a/server/src/test/java/org/eclipse/openvsx/adapter/VSCodeAPITest.java +++ b/server/src/test/java/org/eclipse/openvsx/adapter/VSCodeAPITest.java @@ -63,6 +63,7 @@ import org.eclipse.openvsx.util.TargetPlatform; import org.eclipse.openvsx.util.VersionService; import org.eclipse.openvsx.web.JacksonConfig; +import org.eclipse.openvsx.web.WebUiProperties; import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.openvsx.entities.FileResource.*; @@ -1436,7 +1437,7 @@ private Path mockExtensionBrowse( } @TestConfiguration - @Import({ SecurityConfig.class, MockMvcAsyncConfig.class, JacksonConfig.class }) + @Import({ SecurityConfig.class, MockMvcAsyncConfig.class, JacksonConfig.class, WebUiProperties.class }) static class TestConfig { @Bean IExtensionQueryRequestHandler extensionQueryRequestHandler( @@ -1489,7 +1490,8 @@ LocalVSCodeService localVSCodeService( StorageUtilService storageUtil, ExtensionVersionIntegrityService integrityService, WebResourceService webResourceService, - CacheService cache + CacheService cache, + WebUiProperties webUi ) { return new LocalVSCodeService( repositories, @@ -1498,7 +1500,8 @@ LocalVSCodeService localVSCodeService( storageUtil, integrityService, webResourceService, - cache); + cache, + webUi); } @Bean diff --git a/server/src/test/java/org/eclipse/openvsx/admin/AdminAPITest.java b/server/src/test/java/org/eclipse/openvsx/admin/AdminAPITest.java index 6fe026925..495afceb5 100644 --- a/server/src/test/java/org/eclipse/openvsx/admin/AdminAPITest.java +++ b/server/src/test/java/org/eclipse/openvsx/admin/AdminAPITest.java @@ -80,6 +80,8 @@ import org.eclipse.openvsx.json.UserPublishInfoJson; import org.eclipse.openvsx.mail.MailService; import org.eclipse.openvsx.metrics.ExtensionDownloadMetrics; +import org.eclipse.openvsx.migration.MigrationsProperties; +import org.eclipse.openvsx.mirror.MirrorConfig; import org.eclipse.openvsx.publish.ExtensionVersionIntegrityService; import org.eclipse.openvsx.publish.PublishExtensionVersionHandler; import org.eclipse.openvsx.publish.PublishingConfig; @@ -110,6 +112,7 @@ import org.eclipse.openvsx.util.TargetPlatformVersion; import org.eclipse.openvsx.util.UUIDService; import org.eclipse.openvsx.util.VersionService; +import org.eclipse.openvsx.web.WebUiProperties; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -2612,7 +2615,7 @@ private String errorJson(String message) throws JacksonException { } @TestConfiguration - @Import(SecurityConfig.class) + @Import({ SecurityConfig.class, WebUiProperties.class }) static class TestConfig { @Bean TransactionTemplate transactionTemplate() { @@ -2646,7 +2649,7 @@ UUIDService uuidService() { @Bean AccessTokenConfig tokenConfig() { - return new AccessTokenConfig(); + return new AccessTokenConfig(new MirrorConfig()); } @Bean @@ -2744,6 +2747,8 @@ LocalRegistryService localRegistryService( similarityCheckService, new PublishingConfig(), new TrustedPublishingConfig(), + new MigrationsProperties(), + new WebUiProperties(), Duration.ofSeconds(30)); } diff --git a/server/src/test/java/org/eclipse/openvsx/admin/ConsistencyAPITest.java b/server/src/test/java/org/eclipse/openvsx/admin/ConsistencyAPITest.java index 4e249e62c..3ff9cdec7 100644 --- a/server/src/test/java/org/eclipse/openvsx/admin/ConsistencyAPITest.java +++ b/server/src/test/java/org/eclipse/openvsx/admin/ConsistencyAPITest.java @@ -20,6 +20,7 @@ import org.springframework.boot.security.oauth2.client.autoconfigure.servlet.OAuth2ClientWebSecurityAutoConfiguration; import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest; +import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.test.context.bean.override.mockito.MockitoBean; @@ -31,6 +32,7 @@ import org.eclipse.openvsx.entities.UserData; import org.eclipse.openvsx.util.ErrorResultException; import org.eclipse.openvsx.util.NotFoundException; +import org.eclipse.openvsx.web.WebUiProperties; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; @@ -43,6 +45,7 @@ excludeAutoConfiguration = { OAuth2ClientWebSecurityAutoConfiguration.class } ) @AutoConfigureMockMvc(addFilters = false) +@Import(WebUiProperties.class) class ConsistencyAPITest { @Autowired diff --git a/server/src/test/java/org/eclipse/openvsx/admin/FileDecisionAPITest.java b/server/src/test/java/org/eclipse/openvsx/admin/FileDecisionAPITest.java index 029215fe7..2dd051182 100644 --- a/server/src/test/java/org/eclipse/openvsx/admin/FileDecisionAPITest.java +++ b/server/src/test/java/org/eclipse/openvsx/admin/FileDecisionAPITest.java @@ -18,11 +18,13 @@ import org.springframework.boot.security.oauth2.client.autoconfigure.servlet.OAuth2ClientWebSecurityAutoConfiguration; import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest; +import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.web.servlet.MockMvc; import org.eclipse.openvsx.repositories.RepositoryService; +import org.eclipse.openvsx.web.WebUiProperties; import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -33,6 +35,7 @@ excludeAutoConfiguration = { OAuth2ClientWebSecurityAutoConfiguration.class } ) @AutoConfigureMockMvc(addFilters = false) +@Import(WebUiProperties.class) class FileDecisionAPITest { @Autowired diff --git a/server/src/test/java/org/eclipse/openvsx/admin/ScanAPITest.java b/server/src/test/java/org/eclipse/openvsx/admin/ScanAPITest.java index 650374781..375d81699 100644 --- a/server/src/test/java/org/eclipse/openvsx/admin/ScanAPITest.java +++ b/server/src/test/java/org/eclipse/openvsx/admin/ScanAPITest.java @@ -22,6 +22,7 @@ import org.springframework.boot.security.oauth2.client.autoconfigure.servlet.OAuth2ClientWebSecurityAutoConfiguration; import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest; +import org.springframework.context.annotation.Import; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; import org.springframework.data.util.Streamable; @@ -39,6 +40,7 @@ import org.eclipse.openvsx.storage.StorageUtilService; import org.eclipse.openvsx.util.ErrorResultException; import org.eclipse.openvsx.util.LogService; +import org.eclipse.openvsx.web.WebUiProperties; import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -49,6 +51,7 @@ @WebMvcTest(value = ScanAPI.class, excludeAutoConfiguration = { OAuth2ClientWebSecurityAutoConfiguration.class }) @AutoConfigureMockMvc(addFilters = false) +@Import(WebUiProperties.class) class ScanAPITest { @Autowired diff --git a/server/src/test/java/org/eclipse/openvsx/migration/MigrationSchedulerTest.java b/server/src/test/java/org/eclipse/openvsx/migration/MigrationSchedulerTest.java index 7b625e3a8..c6cfa4b2f 100644 --- a/server/src/test/java/org/eclipse/openvsx/migration/MigrationSchedulerTest.java +++ b/server/src/test/java/org/eclipse/openvsx/migration/MigrationSchedulerTest.java @@ -7,6 +7,8 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.test.util.ReflectionTestUtils; +import org.eclipse.openvsx.mirror.MirrorConfig; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; @@ -21,9 +23,10 @@ class MigrationSchedulerTest { @Test void run_schedulesMigrationItemProcessingUsingTheConfiguredCron() throws Exception { - var migrationScheduler = new MigrationScheduler(orphanNamespaceMigration, scheduler); + var mirrorConfig = new MirrorConfig(); + ReflectionTestUtils.setField(mirrorConfig, "enabled", true); + var migrationScheduler = new MigrationScheduler(orphanNamespaceMigration, scheduler, mirrorConfig); ReflectionTestUtils.setField(migrationScheduler, "migrationItemsCron", "0 * * * *"); - ReflectionTestUtils.setField(migrationScheduler, "mirrorEnabled", true); migrationScheduler.run(new HandlerJobRequest<>(MigrationScheduler.class)); diff --git a/server/src/test/java/org/eclipse/openvsx/trustedpublishing/TrustedPublishingAPITest.java b/server/src/test/java/org/eclipse/openvsx/trustedpublishing/TrustedPublishingAPITest.java index b326fcb23..8bc72e910 100644 --- a/server/src/test/java/org/eclipse/openvsx/trustedpublishing/TrustedPublishingAPITest.java +++ b/server/src/test/java/org/eclipse/openvsx/trustedpublishing/TrustedPublishingAPITest.java @@ -23,6 +23,7 @@ import org.springframework.boot.security.oauth2.client.autoconfigure.servlet.OAuth2ClientWebSecurityAutoConfiguration; import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest; +import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.test.context.bean.override.mockito.MockitoBean; @@ -42,6 +43,7 @@ import org.eclipse.openvsx.trustedpublishing.TrustedPublishingService.TrustedPublishers; import org.eclipse.openvsx.util.ErrorResultException; import org.eclipse.openvsx.util.NotFoundException; +import org.eclipse.openvsx.web.WebUiProperties; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; @@ -61,6 +63,7 @@ excludeAutoConfiguration = { OAuth2ClientWebSecurityAutoConfiguration.class } ) @AutoConfigureMockMvc(addFilters = false) +@Import(WebUiProperties.class) class TrustedPublishingAPITest { private static final String NAMESPACE = "foo"; diff --git a/server/src/test/java/org/eclipse/openvsx/web/ServerErrorControllerTest.java b/server/src/test/java/org/eclipse/openvsx/web/ServerErrorControllerTest.java index dc60f052d..c05c4281d 100644 --- a/server/src/test/java/org/eclipse/openvsx/web/ServerErrorControllerTest.java +++ b/server/src/test/java/org/eclipse/openvsx/web/ServerErrorControllerTest.java @@ -18,6 +18,7 @@ import org.mockito.Mockito; import org.springframework.boot.autoconfigure.web.WebProperties; import org.springframework.boot.webmvc.error.ErrorAttributes; +import org.springframework.test.util.ReflectionTestUtils; import org.springframework.web.bind.annotation.RequestMapping; import static org.assertj.core.api.Assertions.assertThat; @@ -45,10 +46,12 @@ void errorHtmlOverrideHasNoOwnRequestMappingPath() throws Exception { @Test void errorHtmlRedirectsToTheWebuiErrorPage() throws Exception { + var webUi = new WebUiProperties(); + ReflectionTestUtils.setField(webUi, "url", "https://open-vsx.org"); var controller = new ServerErrorController( Mockito.mock(ErrorAttributes.class), - new WebProperties()); - controller.webuiUrl = "https://open-vsx.org"; + new WebProperties(), + webUi); var modelAndView = controller.errorHtml( Mockito.mock(HttpServletRequest.class), diff --git a/server/src/test/java/org/eclipse/openvsx/web/SitemapControllerTest.java b/server/src/test/java/org/eclipse/openvsx/web/SitemapControllerTest.java index 93407b6d1..9cb09b0dd 100644 --- a/server/src/test/java/org/eclipse/openvsx/web/SitemapControllerTest.java +++ b/server/src/test/java/org/eclipse/openvsx/web/SitemapControllerTest.java @@ -73,7 +73,7 @@ void testSitemap() throws Exception { } @TestConfiguration - @Import(SecurityConfig.class) + @Import({ SecurityConfig.class, WebUiProperties.class }) static class TestConfig { @Bean OAuth2UserServices oauth2UserServices( @@ -87,8 +87,8 @@ OAuth2UserServices oauth2UserServices( } @Bean - SitemapService sitemapService(RepositoryService repositories) { - return new SitemapService(repositories); + SitemapService sitemapService(RepositoryService repositories, WebUiProperties webUi) { + return new SitemapService(repositories, webUi); } } }