RemoteStoreConfigPropertiesUtils.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */
  20. package org.openspcoop2.pdd.core.keystore;

  21. import java.util.ArrayList;
  22. import java.util.HashMap;
  23. import java.util.List;
  24. import java.util.Map;
  25. import java.util.Properties;

  26. import org.apache.commons.lang.StringUtils;
  27. import org.openspcoop2.protocol.sdk.state.RequestInfo;
  28. import org.openspcoop2.utils.certificate.KeystoreType;
  29. import org.openspcoop2.utils.certificate.remote.RemoteKeyIdMode;
  30. import org.openspcoop2.utils.certificate.remote.RemoteStoreConfig;
  31. import org.openspcoop2.utils.properties.PropertiesReader;
  32. import org.openspcoop2.utils.transport.http.HttpUtilities;

  33. /**
  34.  * RemoteStoreConfigPropertiesUtils
  35.  *
  36.  * @author Andrea Poli (apoli@link.it)
  37.  * @author $Author$
  38.  * @version $Rev$, $Date$
  39.  */
  40. public class RemoteStoreConfigPropertiesUtils {
  41.    
  42.     private RemoteStoreConfigPropertiesUtils() {}

  43.     public static final String PROPERTY_STORE_NAME = "name";
  44.     public static final String PROPERTY_STORE_LABEL = "label";
  45.    
  46.     public static final String PROPERTY_STORE_TOKEN_POLICY = "tokenPolicy";
  47.    
  48.     public static final String PROPERTY_STORE_URL = "baseUrl";
  49.    
  50.     public static final String PROPERTY_STORE_ID_MODE = "keyId.mode";
  51.     public static final String PROPERTY_STORE_ID_PARAMETER_NAME = "keyId.parameter";
  52.    
  53.     public static final String PROPERTY_STORE_KEY_ALGORITHM = "keyAlgorithm";
  54.    
  55.     public static final String PROPERTY_READ_TIMEOUT = "readTimeout";
  56.     public static final String PROPERTY_CONNECT_TIMEOUT = "connectTimeout";
  57.    
  58.     public static final String PROPERTY_HTTP_BASIC_USERNAME = "http.username";
  59.     public static final String PROPERTY_HTTP_BASIC_USERNAME_DISABLE_VALUE = "#none#";
  60.     public static final String PROPERTY_HTTP_BASIC_PASSWORD = "http.password";

  61.     public static final String PROPERTY_HTTP_HEADER_PREFIX = "http.header.";
  62.    
  63.     public static final String PROPERTY_HTTP_QUERY_PARAMETER_PREFIX = "http.queryParameter.";
  64.    
  65.     public static final String PROPERTY_HTTPS_HOSTNAME_VERIFIER = "https.hostnameVerifier";
  66.     public static final String PROPERTY_HTTPS_TRUST_ALL_CERTS = "https.trustAllCerts";
  67.     public static final String PROPERTY_HTTPS_TRUST_STORE = "https.trustStore";
  68.     public static final String PROPERTY_HTTPS_TRUST_STORE_PASSWORD = "https.trustStore.password";
  69.     public static final String PROPERTY_HTTPS_TRUST_STORE_TYPE = "https.trustStore.type";
  70.     public static final String PROPERTY_HTTPS_TRUST_STORE_CRL = "https.trustStore.crl";

  71.     public static final String PROPERTY_HTTPS_KEY_STORE = "https.keyStore";
  72.     public static final String PROPERTY_HTTPS_KEY_STORE_PASSWORD = "https.keyStore.password";
  73.     public static final String PROPERTY_HTTPS_KEY_STORE_TYPE = "https.keyStore.type";
  74.     public static final String PROPERTY_HTTPS_KEY_ALIAS = "https.key.alias";
  75.     public static final String PROPERTY_HTTPS_KEY_PASSWORD = "https.key.password";

  76.     public static final String PROPERTY_FORWARD_PROXY_URL = "forwardProxy.url";
  77.     public static final String PROPERTY_FORWARD_PROXY_HEADER = "forwardProxy.header";
  78.     public static final String PROPERTY_FORWARD_PROXY_QUERY_PARAMETER = "forwardProxy.queryParameter";
  79.     public static final String PROPERTY_FORWARD_PROXY_BASE64 = "forwardProxy.base64";
  80.    
  81.     public static final String PROPERTY_MULTITENANT = "multiTenant";
  82.    
  83.     public static final String PROPERTY_MULTITENANT_BASEURL_DEFAULT_STRING = "multiTenant.baseUrl.defaultString";
  84.     public static final String PROPERTY_MULTITENANT_BASEURL_PLACEHOLDER = "multiTenant.baseUrl.placeholder";
  85.     public static final String PROPERTY_MULTITENANT_BASEURL_TENANT_STRING = "multiTenant.baseUrl.tenantString";
  86.    
  87.     public static final String PROPERTY_MULTITENANT_BASE_URL_PREFIX = "multiTenant.baseUrl.";

  88.     public static final String PROPERTY_MULTITENANT_HTTP_BASIC_USERNAME_PREFIX = "multiTenant.http.username.";
  89.     public static final String PROPERTY_MULTITENANT_HTTP_BASIC_PASSWORD_PREFIX = "multiTenant.http.password.";

  90.     public static final String PROPERTY_MULTITENANT_HTTP_HEADER_PREFIX = "multiTenant.http.header.";
  91.    
  92.     public static final String PROPERTY_MULTITENANT_HTTP_QUERY_PARAMETER_PREFIX = "multiTenant.http.queryParameter.";
  93.    
  94.    
  95.     public static RemoteStoreConfig read(Properties p, RequestInfo requestInfo) throws KeystoreException {
  96.        
  97.         String storeName = getProperty(p, PROPERTY_STORE_NAME, true);
  98.        
  99.         RemoteStoreConfig config = new RemoteStoreConfig(storeName);
  100.        
  101.         String storeLabel = getProperty(p, PROPERTY_STORE_LABEL, false);
  102.         if(storeLabel!=null && StringUtils.isNotEmpty(storeLabel)) {
  103.             config.setStoreLabel(storeLabel);
  104.         }
  105.        
  106.         String tokenPolicy = getProperty(p, PROPERTY_STORE_TOKEN_POLICY, false);
  107.         if(tokenPolicy!=null && StringUtils.isNotEmpty(tokenPolicy)) {
  108.             config.setTokenPolicy(tokenPolicy);
  109.         }
  110.        
  111.         String storeUrl = getProperty(p, PROPERTY_STORE_URL, true);
  112.         config.setBaseUrl(storeUrl);
  113.        
  114.         String idMode = getProperty(p, PROPERTY_STORE_ID_MODE, true);
  115.         RemoteKeyIdMode keyIdMode = RemoteKeyIdMode.valueOf(idMode);
  116.         config.setIdMode(keyIdMode);
  117.        
  118.         switch (keyIdMode) {
  119.         case HEADER:
  120.         case URL_PARAMETER:
  121.             config.setParameterName(getProperty(p, PROPERTY_STORE_ID_PARAMETER_NAME, true));
  122.             break;
  123.         default:
  124.             break;
  125.         }
  126.        
  127.         String keyAlgo = getProperty(p, PROPERTY_STORE_KEY_ALGORITHM, false);
  128.         if(keyAlgo!=null && StringUtils.isNotEmpty(keyAlgo)) {
  129.             config.setKeyAlgorithm(keyAlgo);
  130.         }

  131.         config.setReadTimeout(getIntProperty(p, PROPERTY_READ_TIMEOUT, false, 15000));
  132.         config.setConnectTimeout(getIntProperty(p, PROPERTY_CONNECT_TIMEOUT, false, HttpUtilities.HTTP_CONNECTION_TIMEOUT));
  133.        
  134.         String basicUsername = getProperty(p, PROPERTY_HTTP_BASIC_USERNAME, false);
  135.         if(basicUsername!=null && StringUtils.isNotEmpty(basicUsername) && !PROPERTY_HTTP_BASIC_USERNAME_DISABLE_VALUE.equals(basicUsername)) {
  136.             config.setBasicUsername(basicUsername);
  137.            
  138.             String basicPassword = getProperty(p, PROPERTY_HTTP_BASIC_PASSWORD, false);
  139.             if(basicPassword!=null && StringUtils.isNotEmpty(basicPassword)) {
  140.                 config.setBasicPassword(basicPassword);
  141.             }
  142.         }
  143.        
  144.         PropertiesReader pReader = new PropertiesReader(p, false);
  145.        
  146.         config.setHeaders(read(pReader, PROPERTY_HTTP_HEADER_PREFIX, config.getHeaders()));
  147.        
  148.         config.setQueryParameters(read(pReader, PROPERTY_HTTP_QUERY_PARAMETER_PREFIX, config.getQueryParameters()));
  149.            
  150.         config.setHostnameVerifier(getBooleanProperty(p, PROPERTY_HTTPS_HOSTNAME_VERIFIER, false, true));  
  151.        
  152.         readTrustStoreConfig(config, p, requestInfo);
  153.        
  154.         readKeyStoreConfig(config, p, requestInfo);
  155.        
  156.         readForwardProxyConfig(config, p);
  157.        
  158.         List<String> multi = readMultitenant(p);
  159.         if(multi!=null && !multi.isEmpty()) {
  160.             setMultitenant(config, multi, p, pReader);
  161.         }
  162.        
  163.         return config;
  164.     }
  165.    
  166.     private static Map<String, String> read(PropertiesReader pReader, String pName, Map<String, String> map) throws KeystoreException {
  167.         Properties properties = null;
  168.         try {
  169.             properties = pReader.readProperties_convertEnvProperties(pName);
  170.         }catch(Exception e) {
  171.             throw new KeystoreException("Property '"+pName+".*' read failed: "+e.getMessage(),e);
  172.         }
  173.         if(properties!=null && !properties.isEmpty()) {
  174.             for (Map.Entry<Object,Object> entry : properties.entrySet()) {
  175.                 if(entry.getKey() instanceof String && entry.getValue() instanceof String) {
  176.                     String name = (String) entry.getKey();
  177.                     String value = (String) entry.getValue();
  178.                     if(map==null) {
  179.                         map = new HashMap<>();
  180.                     }
  181.                     map.put(name, value);
  182.                 }
  183.             }
  184.         }
  185.         return map;
  186.     }
  187.    
  188.     private static List<String> readMultitenant(Properties p) throws KeystoreException{
  189.         List<String> l = new ArrayList<>();
  190.         String multi = getProperty(p, PROPERTY_MULTITENANT, false);
  191.         if(multi==null || StringUtils.isEmpty(multi.trim())) {
  192.             return l;
  193.         }
  194.         multi = multi.trim();
  195.         if(!multi.contains(",")) {
  196.             l.add(multi);
  197.             return l;
  198.         }
  199.         String [] tmp = multi.split(",");
  200.         if(tmp!=null && tmp.length>0) {
  201.             for (String s : tmp) {
  202.                 if(s!=null && StringUtils.isNotEmpty(s.trim())) {
  203.                     l.add(s.trim());
  204.                 }
  205.             }
  206.         }
  207.         return l;
  208.     }
  209.    
  210.     private static void setMultitenant(RemoteStoreConfig config, List<String> multi, Properties p, PropertiesReader pReader) throws KeystoreException {
  211.         config.setMultitenant(true);
  212.        
  213.         String defaultS = getProperty(p, PROPERTY_MULTITENANT_BASEURL_DEFAULT_STRING, false);
  214.         boolean requiredMultitenantBaseUrlConfig = StringUtils.isNotEmpty(defaultS);
  215.         config.setBaseUrlMultitenantDefaultString(defaultS);
  216.         config.setBaseUrlMultitenantPlaceholder(getProperty(p, PROPERTY_MULTITENANT_BASEURL_PLACEHOLDER, requiredMultitenantBaseUrlConfig));
  217.         config.setBaseUrlMultitenantTenantString(getProperty(p, PROPERTY_MULTITENANT_BASEURL_TENANT_STRING, requiredMultitenantBaseUrlConfig));
  218.        
  219.         for (String tenant : multi) {
  220.             setMultitenantBaseUrl(config, tenant, p);
  221.             setMultitenantHttpBasic(config, tenant, p);
  222.             setMultitenantHttp(config, tenant, pReader);
  223.         }
  224.     }
  225.     private static void setMultitenantBaseUrl(RemoteStoreConfig config, String tenant, Properties p) throws KeystoreException {
  226.         String baseUrl = getProperty(p, PROPERTY_MULTITENANT_BASE_URL_PREFIX+tenant, false);
  227.         if(baseUrl!=null) {
  228.             if(config.getMultiTenantBaseUrl()==null) {
  229.                 config.setMultiTenantBaseUrl(new HashMap<>());
  230.             }
  231.             config.getMultiTenantBaseUrl().put(tenant, baseUrl);
  232.         }
  233.     }
  234.     private static void setMultitenantHttpBasic(RemoteStoreConfig config, String tenant, Properties p) throws KeystoreException {
  235.         String username = getProperty(p, PROPERTY_MULTITENANT_HTTP_BASIC_USERNAME_PREFIX+tenant, false);
  236.         if(username!=null) {
  237.             if(config.getMultiTenantBasicUsername()==null) {
  238.                 config.setMultiTenantBasicUsername(new HashMap<>());
  239.             }
  240.             config.getMultiTenantBasicUsername().put(tenant, username);
  241.         }
  242.        
  243.         String password = getProperty(p, PROPERTY_MULTITENANT_HTTP_BASIC_PASSWORD_PREFIX+tenant, false);
  244.         if(password!=null) {
  245.             if(config.getMultiTenantBasicPassword()==null) {
  246.                 config.setMultiTenantBasicPassword(new HashMap<>());
  247.             }
  248.             config.getMultiTenantBasicPassword().put(tenant, password);
  249.         }
  250.     }
  251.     private static void setMultitenantHttp(RemoteStoreConfig config, String tenant, PropertiesReader pReader) throws KeystoreException {
  252.         Map<String, String> header = read(pReader, PROPERTY_MULTITENANT_HTTP_HEADER_PREFIX+tenant+".", config.getMultiTenantHeaders()!=null ? config.getMultiTenantHeaders().get(tenant) : null);
  253.         if(header!=null && !header.isEmpty()) {
  254.             if(config.getMultiTenantHeaders()==null) {
  255.                 config.setMultiTenantHeaders(new HashMap<>());
  256.             }
  257.             config.getMultiTenantHeaders().put(tenant, header);
  258.         }
  259.        
  260.         Map<String, String> query = read(pReader, PROPERTY_MULTITENANT_HTTP_QUERY_PARAMETER_PREFIX+tenant+".", config.getMultiTenantQueryParameters()!=null ? config.getMultiTenantQueryParameters().get(tenant) : null);
  261.         if(query!=null && !query.isEmpty()) {
  262.             if(config.getMultiTenantQueryParameters()==null) {
  263.                 config.setMultiTenantQueryParameters(new HashMap<>());
  264.             }
  265.             config.getMultiTenantQueryParameters().put(tenant, query);
  266.         }
  267.     }
  268.    
  269.     private static void readTrustStoreConfig(RemoteStoreConfig config, Properties p, RequestInfo requestInfo) throws KeystoreException {
  270.         config.setTrustAllCerts(getBooleanProperty(p, PROPERTY_HTTPS_TRUST_ALL_CERTS, false, false));  
  271.         String trustStorePath = getProperty(p, PROPERTY_HTTPS_TRUST_STORE, false);  
  272.         if(trustStorePath!=null && StringUtils.isNotEmpty(trustStorePath)) {
  273.             String trustStorePassword = getProperty(p, PROPERTY_HTTPS_TRUST_STORE_PASSWORD, true);  
  274.             String trustStoreType = getProperty(p, PROPERTY_HTTPS_TRUST_STORE_TYPE, false);
  275.             if(trustStoreType==null || StringUtils.isEmpty(trustStoreType)) {
  276.                 trustStoreType = KeystoreType.JKS.getNome();
  277.             }
  278.             try {
  279.                 config.setTrustStore(GestoreKeystoreCaching.getMerlinTruststore(requestInfo, trustStorePath, trustStoreType, trustStorePassword).getTrustStore().getKeystore());
  280.             }catch(Exception e) {
  281.                 throw new KeystoreException(e.getMessage(),e);
  282.             }
  283.            
  284.             String crl = getProperty(p, PROPERTY_HTTPS_TRUST_STORE_CRL, false);
  285.             if(crl!=null && StringUtils.isNotEmpty(crl)) {
  286.                 try {
  287.                     config.setCrlStore(GestoreKeystoreCaching.getCRLCertstore(requestInfo, crl).getCertStore());
  288.                 }catch(Exception e) {
  289.                     throw new KeystoreException(e.getMessage(),e);
  290.                 }
  291.             }
  292.         }
  293.     }
  294.    
  295.     private static void readKeyStoreConfig(RemoteStoreConfig config, Properties p, RequestInfo requestInfo) throws KeystoreException {
  296.         String keyStorePath = getProperty(p, PROPERTY_HTTPS_KEY_STORE, false);  
  297.         if(keyStorePath!=null && StringUtils.isNotEmpty(keyStorePath)) {
  298.             String keyStorePassword = getProperty(p, PROPERTY_HTTPS_KEY_STORE_PASSWORD, true);  
  299.             String keyStoreType = getProperty(p, PROPERTY_HTTPS_KEY_STORE_TYPE, false);
  300.             if(keyStoreType==null || StringUtils.isEmpty(keyStoreType)) {
  301.                 keyStoreType = KeystoreType.JKS.getNome();
  302.             }
  303.            
  304.             String keyPassword = getProperty(p, PROPERTY_HTTPS_KEY_PASSWORD, true);
  305.             String keyAlias = getProperty(p, PROPERTY_HTTPS_KEY_ALIAS, false);  
  306.            
  307.             try {
  308.                 config.setKeyStore(GestoreKeystoreCaching.getMerlinKeystore(requestInfo, keyStorePath,keyStoreType,keyStorePassword,keyPassword).getKeyStore().getKeystore());
  309.             }catch(Exception e) {
  310.                 throw new KeystoreException(e.getMessage(),e);
  311.             }
  312.             config.setKeyAlias(keyAlias);
  313.             config.setKeyPassword(keyPassword);
  314.         }
  315.     }
  316.    
  317.     private static void readForwardProxyConfig(RemoteStoreConfig config, Properties p) throws KeystoreException {
  318.         String forwardProxyUrl = getProperty(p, PROPERTY_FORWARD_PROXY_URL, false);
  319.         if(forwardProxyUrl!=null && StringUtils.isNotEmpty(forwardProxyUrl)) {
  320.             config.setForwardProxyUrl(forwardProxyUrl);
  321.             config.setForwardProxyHeader(getProperty(p, PROPERTY_FORWARD_PROXY_HEADER, false));
  322.             config.setForwardProxyQueryParameter(getProperty(p, PROPERTY_FORWARD_PROXY_QUERY_PARAMETER, false));
  323.             if(config.getForwardProxyHeader()==null && config.getForwardProxyQueryParameter()==null) {
  324.                 throw new KeystoreException("ForwardProxy property '"+PROPERTY_FORWARD_PROXY_URL+"' require '"+
  325.                         PROPERTY_FORWARD_PROXY_HEADER+"' o '"+
  326.                         PROPERTY_FORWARD_PROXY_QUERY_PARAMETER+"'");
  327.             }
  328.             config.setForwardProxyBase64(getBooleanProperty(p, PROPERTY_FORWARD_PROXY_BASE64, false, true));
  329.         }
  330.     }
  331.    
  332.     private static String getProperty(Properties p, String name, boolean required) throws KeystoreException {
  333.         String tmp = p.getProperty(name);
  334.         if(tmp!=null) {
  335.             return tmp.trim();
  336.         }
  337.         else {
  338.             if(required) {
  339.                 throw new KeystoreException("Property '"+name+"' notFound");
  340.             }
  341.             return null;
  342.         }
  343.     }
  344.     private static boolean getBooleanProperty(Properties p, String name, boolean required, boolean defaultValue) throws KeystoreException {
  345.         String tmp = getProperty(p, name, required);
  346.         if(tmp!=null && StringUtils.isNotEmpty(tmp)) {
  347.             try {
  348.                 return Boolean.valueOf(tmp);
  349.             }catch(Exception t) {
  350.                 throw new KeystoreException("Boolean property '"+name+"' invalid (found value:["+tmp+"]): "+t.getMessage(),t);
  351.             }
  352.         }
  353.         return defaultValue;
  354.     }
  355.     private static int getIntProperty(Properties p, String name, boolean required, int defaultValue) throws KeystoreException {
  356.         String tmp = getProperty(p, name, required);
  357.         if(tmp!=null && StringUtils.isNotEmpty(tmp)) {
  358.             try {
  359.                 return Integer.valueOf(tmp);
  360.             }catch(Exception t) {
  361.                 throw new KeystoreException("Boolean property '"+name+"' invalid (found value:["+tmp+"]): "+t.getMessage(),t);
  362.             }
  363.         }
  364.         return defaultValue;
  365.     }
  366. }