001 package org.cumulus4j.keymanager.front.webapp; 002 003 import java.io.File; 004 import java.io.IOException; 005 import java.util.HashMap; 006 import java.util.Map; 007 008 import javax.ws.rs.core.Context; 009 010 import org.cumulus4j.keymanager.AppServerManager; 011 import org.cumulus4j.keymanager.back.shared.SystemPropertyUtil; 012 import org.cumulus4j.keystore.KeyStore; 013 import org.slf4j.Logger; 014 import org.slf4j.LoggerFactory; 015 016 /** 017 * <p> 018 * Manager for {@link KeyStore}s mapping a <code>keyStoreID</code> to a file name in the local 019 * file system. 020 * </p><p> 021 * One instance of this class is held as a REST-app-singleton and injected into the REST services 022 * via {@link Context} like this example: 023 * </p> 024 * <pre> 025 * private @Context KeyStoreManager keyStoreManager; 026 * </pre> 027 * 028 * @author Marco หงุ่ยตระกูล-Schulze - marco at nightlabs dot de 029 */ 030 public class KeyStoreManager 031 { 032 private static final Logger logger = LoggerFactory.getLogger(KeyStoreManager.class); 033 034 /** 035 * <p> 036 * System property to control which directory is used to manage key store files. If not specified, 037 * the directory "${user.home}/.cumulus4j/" will be used. 038 * </p> 039 * <p> 040 * You can use system properties in this system-property's value. For example 041 * passing "-Dcumulus4j.keyStoreDir=${java.io.tmpdir}/cumulus4j-key-stores" 042 * to the java command will be resolved to "/tmp/cumulus4j-key-stores" on GNU+Linux. 043 * </p> 044 */ 045 public static final String SYSTEM_PROPERTY_KEY_STORE_DIR = "cumulus4j.keyStoreDir"; 046 047 private static File getUserHome() 048 { 049 String userHome = System.getProperty("user.home"); //$NON-NLS-1$ 050 if (userHome == null) 051 throw new IllegalStateException("System property user.home is not set! This should never happen!"); //$NON-NLS-1$ 052 053 return new File(userHome); 054 } 055 056 private Map<String, KeyStore> keyStoreID2keyStore = new HashMap<String, KeyStore>(); 057 058 private Map<String, AppServerManager> keyStoreID2appServerManager = new HashMap<String, AppServerManager>(); 059 060 private File getKeyStoreDir() throws IOException 061 { 062 String keyStoreDirSysPropVal = System.getProperty(SYSTEM_PROPERTY_KEY_STORE_DIR); 063 File keyStoreDir; 064 065 if (keyStoreDirSysPropVal == null || keyStoreDirSysPropVal.trim().isEmpty()) { 066 keyStoreDir = new File(getUserHome(), ".cumulus4j"); 067 logger.info( 068 "getSingletons: System property '{}' is empty or not specified. Using default keyStoreDir '{}'.", 069 SYSTEM_PROPERTY_KEY_STORE_DIR, keyStoreDir.getAbsolutePath() 070 ); 071 } 072 else { 073 String keyStoreDirSysPropValResolved = SystemPropertyUtil.resolveSystemProperties(keyStoreDirSysPropVal); 074 keyStoreDir = new File(keyStoreDirSysPropValResolved); 075 logger.info( 076 "getSingletons: System property '{}' was set to '{}'. Using keyStoreDir '{}'.", 077 new Object[] { SYSTEM_PROPERTY_KEY_STORE_DIR, keyStoreDirSysPropVal, keyStoreDir.getAbsolutePath() } 078 ); 079 } 080 081 if (!keyStoreDir.isDirectory()) { 082 keyStoreDir.mkdirs(); 083 084 if (!keyStoreDir.isDirectory()) 085 throw new IOException("Creating directory \"" + keyStoreDir.getAbsolutePath() + "\" failed! Check permissions!"); 086 } 087 return keyStoreDir; 088 } 089 090 /** 091 * Get the <code>KeyStore</code> identified by the given <code>keyStoreID</code>. If it does not exist, 092 * it is implicitely created. 093 * @param keyStoreID the identfier of the {@link KeyStore} to be returned. Must not be <code>null</code>. 094 * @return the <code>KeyStore</code> identified by the given <code>keyStoreID</code>. 095 * @throws IOException if reading from / writing to the local file system failed. 096 */ 097 public synchronized KeyStore getKeyStore(String keyStoreID) throws IOException 098 { 099 if (keyStoreID == null) 100 throw new IllegalArgumentException("keyStoreID == null"); 101 102 KeyStore keyStore = keyStoreID2keyStore.get(keyStoreID); 103 if (keyStore == null) { 104 File keyStoreFile = new File(getKeyStoreDir(), keyStoreID + ".keystore"); 105 keyStore = new KeyStore(keyStoreID, keyStoreFile); 106 keyStoreID2keyStore.put(keyStoreID, keyStore); 107 } 108 return keyStore; 109 } 110 111 /** 112 * Get the <code>AppServerManager</code> that is assigned (in a 1-1-relation) to the {@link KeyStore} 113 * identified by the given ID. 114 * 115 * @param keyStoreID the identfier of the {@link KeyStore} whose <code>AppServerManager</code> shall be returned. Must not be <code>null</code>. 116 * @return the <code>AppServerManager</code> that is assigned (in a 1-1-relation) to the {@link KeyStore} 117 * identified by the given ID. 118 * @throws IOException if reading from / writing to the local file system failed. 119 */ 120 public synchronized AppServerManager getAppServerManager(String keyStoreID) throws IOException 121 { 122 if (keyStoreID == null) 123 throw new IllegalArgumentException("keyStoreID == null"); 124 125 AppServerManager appServerManager = keyStoreID2appServerManager.get(keyStoreID); 126 if (appServerManager == null) { 127 appServerManager = new AppServerManager(getKeyStore(keyStoreID)); 128 keyStoreID2appServerManager.put(keyStoreID, appServerManager); 129 } 130 return appServerManager; 131 } 132 }