package org.jboss.resteasy.keystone.server; import org.infinispan.Cache; import org.infinispan.configuration.cache.Configuration; import org.infinispan.configuration.cache.ConfigurationBuilder; import org.infinispan.configuration.global.GlobalConfiguration; import org.infinispan.configuration.global.GlobalConfigurationBuilder; import org.infinispan.eviction.EvictionStrategy; import org.infinispan.manager.DefaultCacheManager; import org.infinispan.manager.EmbeddedCacheManager; import org.jboss.resteasy.keystone.core.i18n.LogMessages; import org.jboss.resteasy.keystone.core.i18n.Messages; import org.jboss.resteasy.keystone.model.Mappers; import org.jboss.resteasy.spi.ResteasyConfiguration; import org.jboss.resteasy.spi.ResteasyProviderFactory; import javax.ws.rs.core.Configurable; import javax.ws.rs.core.Context; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.security.KeyStore; import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.util.HashSet; import java.util.Set; import java.util.concurrent.TimeUnit; /** * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @version $Revision: 1 $ */ public class SkeletonKeyApplication { public static final String SKELETON_KEY_INFINISPAN_CONFIG_FILE = "skeleton.key.infinispan.config.file"; public static final String SKELETON_KEY_INFINISPAN_CACHE_NAME = "skeleton.key.infinispan.cache.name"; Configurable configurable; protected Set<Object> singletons = new HashSet<Object>(); protected PrivateKey privateKey; protected X509Certificate certificate; protected RolesService roles; protected ProjectsService projects; protected UsersService users; protected TokenService tokenService; protected Cache cache; public SkeletonKeyApplication(@Context Configurable confgurable) { this.configurable = confgurable; String exp = getConfigProperty("skeleton.key.token.expiration"); String unit = getConfigProperty("skeleton.key.token.expiration.unit"); long expiration = (exp == null) ? 30 : Long.parseLong(exp); Mappers.registerContextResolver(confgurable); cache = findCache(); users = new UsersService(cache); singletons.add(users); roles = new RolesService(cache); singletons.add(roles); projects = new ProjectsService(cache, users, roles); singletons.add(projects); TimeUnit timeUnit = (unit == null) ? TimeUnit.MINUTES : TimeUnit.valueOf(unit); tokenService = new TokenService(cache, expiration, timeUnit, projects, users); singletons.add(tokenService); initKeyPair(); singletons.add(new ServerTokenAuthFilter(tokenService)); } protected void initKeyPair() { try { String keyStoreFile = getConfigProperty("skeleton.key.keyStoreFile"); String keyStorePassword = getConfigProperty("skeleton.key.keyStorePassword"); String alias = getConfigProperty("skeleton.key.alias"); KeyStore keyStore = null; if (keyStoreFile == null) { String path = getConfigProperty("skeleton.key.keyStorePath"); if (path == null) { LogMessages.LOGGER.warn(Messages.MESSAGES.noKeystoreProvided()); return; } InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(path); if (is == null) { throw new RuntimeException(Messages.MESSAGES.keystorePathInvalid(path)); } keyStore = KeyStore.getInstance("jks"); keyStore.load(is, keyStorePassword.toCharArray()); is.close(); } else { keyStore = KeyStore.getInstance("jks"); InputStream is = new FileInputStream(keyStoreFile); keyStore.load(is, keyStorePassword.toCharArray()); is.close(); } privateKey = (PrivateKey)keyStore.getKey(alias, keyStorePassword.toCharArray()); if (privateKey == null) throw new RuntimeException(Messages.MESSAGES.privateKeyNull()); certificate = (X509Certificate)keyStore.getCertificate(alias); if (certificate == null) throw new RuntimeException(Messages.MESSAGES.certificateNull()); tokenService.setPrivateKey(privateKey); tokenService.setCertificate(certificate); } catch (Exception e) { throw new RuntimeException(e); } } public RolesService getRoles() { return roles; } public ProjectsService getProjects() { return projects; } public UsersService getUsers() { return users; } public TokenService getTokenService() { return tokenService; } public Set<Object> getSingletons() { return singletons; } protected ResteasyConfiguration getResteasyConfiguration() { return ResteasyProviderFactory.getContextData(ResteasyConfiguration.class); } protected String getConfigProperty(String name) { String val = (String)configurable.getConfiguration().getProperty(name); if (val != null) return val; ResteasyConfiguration config = getResteasyConfiguration(); if (config == null) return null; return config.getParameter(name); } public Cache getCache() { return cache; } protected Cache findCache() { Cache cache = (Cache)configurable.getConfiguration().getProperty("skeleton.key.cache"); if (cache != null) return cache; cache = getXmlCache(); if (cache != null) return cache; return getDefaultCache(); } protected Cache getDefaultCache() { GlobalConfiguration gconfig = new GlobalConfigurationBuilder() .globalJmxStatistics() .allowDuplicateDomains(true) .enable() .jmxDomain("custom-cache") .build(); Configuration configuration = new ConfigurationBuilder() .eviction() .strategy(EvictionStrategy.NONE) .maxEntries(1000) .jmxStatistics().enable() .build(); ConfigurationBuilder configBuilder = new ConfigurationBuilder().read(configuration); EmbeddedCacheManager manager = new DefaultCacheManager(gconfig, configuration); return manager.getCache("custom-cache"); } protected Cache getXmlCache() { String path = getConfigProperty(SKELETON_KEY_INFINISPAN_CONFIG_FILE); if (path == null) return null; String name = getConfigProperty(SKELETON_KEY_INFINISPAN_CACHE_NAME); if (name == null) throw new RuntimeException(Messages.MESSAGES.needToSpecifyCacheName()); try { return new DefaultCacheManager(path).getCache(name); } catch (IOException e) { throw new RuntimeException(e); } } }