From e12e11446fd421845ef1fdf42e17134fb07f6159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Garc=C3=ADa?= Date: Thu, 7 Sep 2023 14:44:30 +0200 Subject: [PATCH] If the http proxy is configured in Java system properties, don't use the proxy settings configuration --- .../org/fao/geonet/kernel/url/UrlChecker.java | 6 +- .../main/java/org/fao/geonet/lib/NetLib.java | 73 +++++++----- .../fao/geonet/lib/ProxyConfiguration.java | 108 ++++++++++++++++++ .../java/org/fao/geonet/api/site/SiteApi.java | 29 ++++- .../js/admin/SystemSettingsController.js | 20 +++- .../resources/catalog/locales/en-admin.json | 3 +- .../templates/admin/settings/system.html | 6 + .../main/java/org/fao/geonet/Geonetwork.java | 16 ++- 8 files changed, 219 insertions(+), 42 deletions(-) create mode 100644 core/src/main/java/org/fao/geonet/lib/ProxyConfiguration.java diff --git a/core/src/main/java/org/fao/geonet/kernel/url/UrlChecker.java b/core/src/main/java/org/fao/geonet/kernel/url/UrlChecker.java index 71b0e12d6ac5..a9b65a61802d 100644 --- a/core/src/main/java/org/fao/geonet/kernel/url/UrlChecker.java +++ b/core/src/main/java/org/fao/geonet/kernel/url/UrlChecker.java @@ -1,5 +1,5 @@ //============================================================================= -//=== Copyright (C) 2001-2019 Food and Agriculture Organization of the +//=== Copyright (C) 2001-2023 Food and Agriculture Organization of the //=== United Nations (FAO-UN), United Nations World Food Programme (WFP) //=== and United Nations Environment Programme (UNEP) //=== @@ -31,6 +31,7 @@ import org.fao.geonet.constants.Geonet; import org.fao.geonet.domain.LinkStatus; import org.fao.geonet.kernel.setting.SettingManager; +import org.fao.geonet.lib.Lib; import org.fao.geonet.lib.NetLib; import org.fao.geonet.utils.GeonetHttpRequestFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -149,8 +150,7 @@ public Void apply(@Nullable HttpClientBuilder originalConfig) { Log.info(Geonet.GEONETWORK,"UrlChecker: cannot determine hostname from url: "+url); } //now we have hostname, we can configure proxy - NetLib netLib = new NetLib(); - netLib.setupProxy(settingManager, originalConfig, hostname); + Lib.net.setupProxy(settingManager, originalConfig, hostname); return null; } }; diff --git a/core/src/main/java/org/fao/geonet/lib/NetLib.java b/core/src/main/java/org/fao/geonet/lib/NetLib.java index 353d49d59647..79c48e36c4ef 100644 --- a/core/src/main/java/org/fao/geonet/lib/NetLib.java +++ b/core/src/main/java/org/fao/geonet/lib/NetLib.java @@ -1,5 +1,5 @@ //============================================================================= -//=== Copyright (C) 2001-2022 Food and Agriculture Organization of the +//=== Copyright (C) 2001-2023 Food and Agriculture Organization of the //=== United Nations (FAO-UN), United Nations World Food Programme (WFP) //=== and United Nations Environment Programme (UNEP) //=== @@ -34,7 +34,6 @@ import org.fao.geonet.GeonetContext; import org.fao.geonet.constants.Geonet; import org.fao.geonet.kernel.setting.SettingManager; -import org.fao.geonet.kernel.setting.Settings; import org.fao.geonet.utils.Log; import org.fao.geonet.utils.XmlRequest; @@ -51,6 +50,18 @@ import jeeves.server.context.ServiceContext; public class NetLib { + private ProxyConfiguration proxyConfiguration; + + public ProxyConfiguration getProxyConfiguration() { + return proxyConfiguration; + } + + public NetLib() { + boolean isProxyConfiguredInSystemProperties = StringUtils.isNotBlank(System.getProperty("http.proxyHost")) || + StringUtils.isNotBlank(System.getProperty("https.proxyHost")); + + proxyConfiguration = new ProxyConfiguration(isProxyConfiguredInSystemProperties); + } public void setupProxy(ServiceContext context, XmlRequest req) { GeonetContext gc = (GeonetContext) context.getHandlerContext(Geonet.CONTEXT_NAME); @@ -66,12 +77,14 @@ public void setupProxy(ServiceContext context, XmlRequest req) { */ public void setupProxy(SettingManager sm, XmlRequest req) { - boolean enabled = sm.getValueAsBool(Settings.SYSTEM_PROXY_USE, false); - String host = sm.getValue(Settings.SYSTEM_PROXY_HOST); - String port = sm.getValue(Settings.SYSTEM_PROXY_PORT); - String username = sm.getValue(Settings.SYSTEM_PROXY_USERNAME); - String password = sm.getValue(Settings.SYSTEM_PROXY_PASSWORD); - String ignoreHostList = sm.getValue(Settings.SYSTEM_PROXY_IGNOREHOSTLIST); + proxyConfiguration.refresh(sm); + + boolean enabled = proxyConfiguration.isEnabled(); + String host = proxyConfiguration.getHost(); + String port = proxyConfiguration.getPort(); + String username = proxyConfiguration.getUsername(); + String password = proxyConfiguration.getPassword(); + String ignoreHostList = proxyConfiguration.getIgnoreHostList(); if (!enabled) { req.setUseProxy(false); @@ -108,12 +121,14 @@ public CredentialsProvider setupProxy(ServiceContext context, HttpClientBuilder * Setup proxy for http client */ public CredentialsProvider setupProxy(SettingManager sm, HttpClientBuilder client, String requestHost) { - boolean enabled = sm.getValueAsBool(Settings.SYSTEM_PROXY_USE, false); - String host = sm.getValue(Settings.SYSTEM_PROXY_HOST); - String port = sm.getValue(Settings.SYSTEM_PROXY_PORT); - String username = sm.getValue(Settings.SYSTEM_PROXY_USERNAME); - String password = sm.getValue(Settings.SYSTEM_PROXY_PASSWORD); - String ignoreHostList = sm.getValue(Settings.SYSTEM_PROXY_IGNOREHOSTLIST); + proxyConfiguration.refresh(sm); + + boolean enabled = proxyConfiguration.isEnabled(); + String host = proxyConfiguration.getHost(); + String port = proxyConfiguration.getPort(); + String username = proxyConfiguration.getUsername(); + String password = proxyConfiguration.getPassword(); + String ignoreHostList = proxyConfiguration.getIgnoreHostList(); CredentialsProvider provider = new BasicCredentialsProvider(); if (enabled) { @@ -153,13 +168,17 @@ public void setupProxy(ServiceContext context) { * Setup proxy for http client */ public void setupProxy(SettingManager sm) { - boolean useProxy = sm.getValueAsBool(Settings.SYSTEM_PROXY_USE, false); + proxyConfiguration.refresh(sm); - if (useProxy) { - String host = sm.getValue(Settings.SYSTEM_PROXY_HOST); - String port = sm.getValue(Settings.SYSTEM_PROXY_PORT); - String username = sm.getValue(Settings.SYSTEM_PROXY_USERNAME); - String ignoreHostList = sm.getValue(Settings.SYSTEM_PROXY_IGNOREHOSTLIST); + // If the proxy is configured in the system properties, + // ignore the proxy configuration in the system settings. + if (proxyConfiguration.isProxyConfiguredInSystemProperties()) return; + + if (proxyConfiguration.isEnabled()) { + String host = proxyConfiguration.getHost(); + String port = proxyConfiguration.getPort(); + String username = proxyConfiguration.getUsername(); + String ignoreHostList = proxyConfiguration.getIgnoreHostList(); Properties props = System.getProperties(); props.put("http.proxyHost", host); @@ -189,12 +208,14 @@ public URLConnection setupProxy(ServiceContext context, URL url) throws IOExcept GeonetContext gc = (GeonetContext) context.getHandlerContext(Geonet.CONTEXT_NAME); SettingManager sm = gc.getBean(SettingManager.class); - boolean enabled = sm.getValueAsBool(Settings.SYSTEM_PROXY_USE, false); - String host = sm.getValue(Settings.SYSTEM_PROXY_HOST); - String port = sm.getValue(Settings.SYSTEM_PROXY_PORT); - String username = sm.getValue(Settings.SYSTEM_PROXY_USERNAME); - String password = sm.getValue(Settings.SYSTEM_PROXY_PASSWORD); - String ignoreHostList = sm.getValue(Settings.SYSTEM_PROXY_IGNOREHOSTLIST); + proxyConfiguration.refresh(sm); + + boolean enabled = proxyConfiguration.isEnabled(); + String host = proxyConfiguration.getHost(); + String port = proxyConfiguration.getPort(); + String username = proxyConfiguration.getUsername(); + String password = proxyConfiguration.getPassword(); + String ignoreHostList = proxyConfiguration.getIgnoreHostList(); URLConnection conn = null; if (enabled) { diff --git a/core/src/main/java/org/fao/geonet/lib/ProxyConfiguration.java b/core/src/main/java/org/fao/geonet/lib/ProxyConfiguration.java new file mode 100644 index 000000000000..44b9f3f21aab --- /dev/null +++ b/core/src/main/java/org/fao/geonet/lib/ProxyConfiguration.java @@ -0,0 +1,108 @@ +//============================================================================= +//=== Copyright (C) 2001-2022 Food and Agriculture Organization of the +//=== United Nations (FAO-UN), United Nations World Food Programme (WFP) +//=== and United Nations Environment Programme (UNEP) +//=== +//=== This program is free software; you can redistribute it and/or modify +//=== it under the terms of the GNU General Public License as published by +//=== the Free Software Foundation; either version 2 of the License, or (at +//=== your option) any later version. +//=== +//=== This program is distributed in the hope that it will be useful, but +//=== WITHOUT ANY WARRANTY; without even the implied warranty of +//=== MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +//=== General Public License for more details. +//=== +//=== You should have received a copy of the GNU General Public License +//=== along with this program; if not, write to the Free Software +//=== Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA +//=== +//=== Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2, +//=== Rome - Italy. email: geonetwork@osgeo.org +//============================================================================== + +package org.fao.geonet.lib; + +import org.apache.commons.lang.StringUtils; +import org.fao.geonet.kernel.setting.SettingManager; +import org.fao.geonet.kernel.setting.Settings; + +/** + * Class to abstract the http proxy configuration from Java system properties or GeoNetwork configuration. + */ +public class ProxyConfiguration { + private boolean enabled = false; + + private boolean isProxyConfiguredInSystemProperties = false; + private String host; + private String port; + private String username; + private String password; + private String ignoreHostList; + + public boolean isEnabled() { + return enabled; + } + + public boolean isProxyConfiguredInSystemProperties() { + return isProxyConfiguredInSystemProperties; + } + + public String getHost() { + return host; + } + + public String getPort() { + return port; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + public String getIgnoreHostList() { + return ignoreHostList; + } + + public ProxyConfiguration(boolean isProxyConfiguredInSystemProperties) { + this.isProxyConfiguredInSystemProperties = isProxyConfiguredInSystemProperties; + if (this.isProxyConfiguredInSystemProperties) { + this.enabled = true; + } + } + + public void refresh(SettingManager settingManager) { + this.enabled = this.isProxyConfiguredInSystemProperties || + settingManager.getValueAsBool(Settings.SYSTEM_PROXY_USE, false); + + if (this.enabled) { + if (this.isProxyConfiguredInSystemProperties) { + if (StringUtils.isNotBlank(System.getProperty("https.proxyHost"))) { + this.host = System.getProperty("https.proxyHost"); + this.port = System.getProperty("https.proxyPort"); + this.username = System.getProperty("https.proxyUser", ""); + this.password = System.getProperty("https.proxyPassword", ""); + } else { + this.host = System.getProperty("http.proxyHost"); + this.port = System.getProperty("http.proxyPort"); + this.username = System.getProperty("http.proxyUser", ""); + this.password = System.getProperty("http.proxyPassword", ""); + } + + this.ignoreHostList = System.getProperty("http.nonProxyHosts", ""); + + } else { + this.host = settingManager.getValue(Settings.SYSTEM_PROXY_HOST); + this.port = settingManager.getValue(Settings.SYSTEM_PROXY_PORT); + this.username = settingManager.getValue(Settings.SYSTEM_PROXY_USERNAME); + this.password = settingManager.getValue(Settings.SYSTEM_PROXY_PASSWORD); + this.ignoreHostList = settingManager.getValue(Settings.SYSTEM_PROXY_IGNOREHOSTLIST); + + } + } + } +} diff --git a/services/src/main/java/org/fao/geonet/api/site/SiteApi.java b/services/src/main/java/org/fao/geonet/api/site/SiteApi.java index e00acdba5eaa..00f478966be1 100644 --- a/services/src/main/java/org/fao/geonet/api/site/SiteApi.java +++ b/services/src/main/java/org/fao/geonet/api/site/SiteApi.java @@ -64,6 +64,7 @@ import org.fao.geonet.kernel.setting.SettingManager; import org.fao.geonet.kernel.setting.Settings; import org.fao.geonet.lib.Lib; +import org.fao.geonet.lib.ProxyConfiguration; import org.fao.geonet.repository.*; import org.fao.geonet.repository.specification.MetadataSpecs; import org.fao.geonet.resources.Resources; @@ -161,12 +162,12 @@ public static void reloadServices(ServiceContext context) throws Exception { try { // Load proxy information into Jeeves ProxyInfo pi = JeevesProxyInfo.getInstance(); - boolean useProxy = settingMan.getValueAsBool(Settings.SYSTEM_PROXY_USE, false); + boolean useProxy = Lib.net.getProxyConfiguration().isEnabled(); if (useProxy) { - String proxyHost = settingMan.getValue(Settings.SYSTEM_PROXY_HOST); - String proxyPort = settingMan.getValue(Settings.SYSTEM_PROXY_PORT); - String username = settingMan.getValue(Settings.SYSTEM_PROXY_USERNAME); - String password = settingMan.getValue(Settings.SYSTEM_PROXY_PASSWORD); + String proxyHost = Lib.net.getProxyConfiguration().getHost(); + String proxyPort = Lib.net.getProxyConfiguration().getPort(); + String username = Lib.net.getProxyConfiguration().getUsername(); + String password = Lib.net.getProxyConfiguration().getPassword(); pi.setProxyInfo(proxyHost, Integer.valueOf(proxyPort), username, password); } else { pi.setProxyInfo(null, -1, null, null); @@ -735,6 +736,24 @@ public StatusValueNotificationLevel[] getNotificationLevel() { return StatusValueNotificationLevel.values(); } + @io.swagger.v3.oas.annotations.Operation( + summary = "Get proxy configuration details", + description = "Get the proxy configuration.") + @RequestMapping( + path = "/info/proxy", + produces = MediaType.APPLICATION_JSON_VALUE, + method = RequestMethod.GET) + @ResponseStatus(HttpStatus.OK) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Proxy configuration.") + }) + @PreAuthorize("hasAuthority('Administrator')") + @ResponseBody + public ProxyConfiguration getProxyConfiguration( + ) { + return Lib.net.getProxyConfiguration(); + } + @io.swagger.v3.oas.annotations.Operation( summary = "Set catalog logo", description = "Logos are stored in the data directory " + diff --git a/web-ui/src/main/resources/catalog/js/admin/SystemSettingsController.js b/web-ui/src/main/resources/catalog/js/admin/SystemSettingsController.js index 310ef2ad805e..c0f864695622 100644 --- a/web-ui/src/main/resources/catalog/js/admin/SystemSettingsController.js +++ b/web-ui/src/main/resources/catalog/js/admin/SystemSettingsController.js @@ -192,6 +192,11 @@ * element name in XML Jeeves request element). */ function loadSettings() { + $http.get("../api/site/info/proxy").then(function (response) { + $scope.isProxyConfiguredInSystemProperties = + response.data.proxyConfiguredInSystemProperties; + }); + $http.get("../api/site/info/build").then(function (response) { $scope.systemInfo = response.data; }); @@ -269,10 +274,23 @@ var level2name = level1name + "/" + tokens[1]; if (sectionsLevel2.indexOf(level2name) === -1) { sectionsLevel2.push(level2name); + + var sectionChildren; + + // Remove the system proxy information if using Java system properties + if ( + level2name === "system/proxy" && + $scope.isProxyConfiguredInSystemProperties + ) { + sectionChildren = []; + } else { + sectionChildren = filterBySection($scope.settings, level2name); + } + $scope.sectionsLevel1[level1name].children.push({ name: level2name, position: $scope.settings[i].position, - children: filterBySection($scope.settings, level2name) + children: sectionChildren }); } } diff --git a/web-ui/src/main/resources/catalog/locales/en-admin.json b/web-ui/src/main/resources/catalog/locales/en-admin.json index 41f07b2fdd6f..71654c5a13fa 100644 --- a/web-ui/src/main/resources/catalog/locales/en-admin.json +++ b/web-ui/src/main/resources/catalog/locales/en-admin.json @@ -1452,6 +1452,7 @@ "ui-footerCustomMenu-help": "List of static page IDs associated with the footer section to display: